Ілюстрований самовчитель з Visual Basic
Створення делегата
Почнемо зі створення найпростішого делегата, що інкапсулює об'єкт і "покажчик" на процедуру цього об'єкта. Як показано нижче, синтаксис створення об'єктів трохи складніший за синтаксис, який використовується при створенні простих об'єктів. Насамперед нам знадобиться клас, який містить процедуру з певною сигнатурою:
Щоб створити делегат для зворотного виклику цієї процедури, необхідно повідомити компілятор про використання делегата для процедури з одним рядковим параметром. Перший крок цього сценарію виконується за межамиSub Main наступним рядком:
Зверніть увагу: у цьому рядку ми не оголошуємо делегат, а визначаємо його. Компілятор VB.NET автоматично створює новий класStringSubDelegate, похідний від System.Delegate.
Компілятор VB.NET розуміє, що делегат створюється для test test. Також можна скористатися ключовим словомNew, проте це робиться рідко, оскількиNew неявно викликається у першій формі:
Після того, як делегат буде створений, інкапсульована в ньому процедура викликається методомInvoke класуDelegate, як у наступному фрагменті:
Примітка Насправді використовуватиInvoke необов'язково – достатньо передати делегату потрібні параметри. VB.NET зрозуміє командуaDelegate("Hello"), яка виглядає значно простіше.
У цьому неважко переконатися, переглядаючи отриманий код IL за допомогою програми ILDASM.
Погодьтеся, такий спосіб виведення в консольному вікні рядка HelloHello виглядає дещо незвичайно!
Втім, "якщо це і безумство, то свого роду послідовне". Припустимо, ви вирішили вдосконалити свій клас, щоб замість простого виведеннятексту в консольному вікні з'являлося вікно повідомлення. Для цього достатньо внести зміни, виділені жирним шрифтом у наступному лістингу:
Оскільки для делегата важлива лише сигнатура інкапсульованого методу, він легко перемикається на інший метод. Потрібно створити нову версію для виведення інформації у вікні налагодження (замість консолі та вікна повідомлення)? Достатньо внести кілька змін до делегата і додати до класу функцію, що інкапсулюється делегатом.
Найважливіша особливість делегатів у тому, що з методом виробляється на стадії виконання. Таким чином, делегати у поєднанні з явним або неявним викликом методуInvoke за своїми можливостями значно перевершують функцію VB6CallByName.