:: Меню ::

Головна
  • Про сайт
  • Введення
  • Середовище програмування VB .NET: Visual Studio .NET
  • Вирази, оператори і передача управління
  • Класи і об'єкти
  •  Спадкоємство і інтерфейси
  • Обробка подій і делегати
  • Обробка помилок в VB .NET
  • Форми Windows, графічний вивід і друк
  • Уведення-виведення
  •  Багатопотокові застосування
  • Підтримка баз-даних в VB .NET
  • Короткий огляд ASP .NET
  • Складки .NET, установка додатків і COM Interop
  • Книга для гостей
    Контакти
    Добавити у вибране

    :: Друзі ::

     
     

    :: Лічильники ::

    = =

     

     

     

     

    Відключення обробників подій

    Обробники подій, що динамічно призначаються командою Addhandler, відключаються командою Removehandler, якою повинні передаватися такі самі аргументи, як і при відповідному виклику Addhandlеr. Зазвичай для видалення обробників, що динамічно призначаються, добре підходить метод Dispose. З цієї причини в кожному класі, що використовує динамічне призначення обробників, рекомендується реалізувати інтерфейс Idisposable — це нагадає користувачам класу про необхідність виклику Dispose.

    Обробка подій в ієрархії спадкоємства

    Похідний клас може у будь-який момент ініціювати відкриті або захищені події свого базового класу, при цьому подія ідентифікується ключовим словом Mybase. Крім того, похідні класи автоматично успадковують всі обробники відкритих і захищених подій своїх предків. Час від часу в похідному класі виникає необхідність в перевизначенні методів, використовуваних при обробці відкритих і захищених подій базового класу. Для цієї мети використовується конструкція Handles Mybase. Приклад:

    Public Class Parentclass

    Public Event Parenteventtbyval athing As Object.

    Byval E As System.EventArgs)

    ' Програмний код End Class

    ' Похідний клас

    Public Class Childclass

    Inherits Parentclass

    Sub Eventhandler(Byval x As Integer)

    Handles Mybase Parentevent

    'Обробка подій базового класу

    End Sub

    End Class

    Делегати

    При використанні механізму зворотного виклику доводиться виконувати допоміжні операції для реєстрації функцій, що викликаються. У частині, що залишилася, розділи буде показано, що при цьому відбувається і як за допомогою цих операцій добитися максимальної ефективності зворотного виклику.

    Механізм зворотного виклику (а отже, і події) в VB .NET залежить від особливого різновиду об'єктів .NET, званих делегатами. Делегат є екземпляром класу System.Delegate. У простому випадку в делегатові інкапсулюється об'єкт і адреса заданої функції або процедури цього об'єкту. Такі делегати ідеально підходять для схем зворотного виклику на зразок тієї, що використовується при обробці подій. Чому? Тому що делегат містить всю інформацію, необхідну для зворотного виклику, і може використовуватися для виклику потрібного методу об'єкту-приймача.

    Але перш, ніж переходити до опису роботи з делегатами, варто підкреслити одну важливу обставину. Хоча обробка подій на платформі .NET заснована на використанні делегатів, в переважній більшості випадків вам не доведеться працювати безпосередньо з делегатами. Команда Addhandl ег надає у ваше розпорядження все необхідне для гнучкої обробки подій в VB .NET (втім, як ви незабаром побачите, у делегатів є і інші застосування).

    У делегатах також можуть інкапсулюватися загальні методи класу без прив'язки ккон-кретному екземпляру. Крім того, в групових делегатах інкапсулюється відразу декілька об'єктів з декількома процедурами.

    Традиційні засоби виклику функції за адресою були засновані на мовній підтримці покажчиків на функції. Як показано в наступному врізанні, застосування покажчиків на функції зв'язане з потенційним ризиком. В порівнянні з покажчиками на функції делегати забезпечують додатковий захист, значення якого не варто недооцінювати.

    Покажчики на функції в Vb6 . При викликах функцій API часто передається адреса функції для зворотного виклику, тому в Vb6 підтримувався оператор Addressof. У Vb6 адреса функції могла передаватися при будь-якому виклику API. Але що відбувалося, якщо список параметрів функції, адреса якої передавалася при виклику, відрізнялася від передбачуваного? Зазвичай це приводило до загальної помилки захисту (GPF) і навіть до фатальних збоїв з появою синього екрану.

    Таким чином, довільні покажчики на функції володіють принциповим недоліком: компілятор не може перевірити, що такий покажчик відноситься до функції правильного типу. Делегати є різновидом покажчиків на функції, безпечних по відношенню до типів. Слідуючи принципу «довіряй, але перевіряй», компілятор автоматично перевіряє сигнатуру функції, що викликається, — такий варіант працює набагато надійніше.

    Створення делегата

    Почнемо із створення простого делегата, що інкапсулює об'єкт і «покажчик» на процедуру цього об'єкту. Як показано нижче, синтаксис створення об'єктів трохи складніший за синтаксис, використовуваний при створенні простих об'єктів. Перш за все нам знадобиться клас, що містить процедуру з певною сигнатурою:

    Class Classforstringsubdelegate

    ' Використовувати конструктор за умовчанням

    Public Sub Testsub(Byval astring As String)

    Console. Writeline(astring Sastring)

    End Sub

    End Class

    Щоб створити делегат для зворотного виклику цієї процедури, необхідно повідомити компілятор про використання делегата для процедури з одним строковим параметром. Перший крок цього сценарію виконується за межами Sub Main наступним рядком:

    Public Delegate Sub Stringsubdelegate(Byval

    astring As String)

    Звернете увагу: у цьому рядку ми не оголошуємо делегат, а визначаємо його. Компілятор VB .NET автоматично створює новий клас Stringsubdel egate, похідний від System . Delegate1.

    Далі в процедурі Sub Main екземпляр класу делегата створюється оператором Addressof для адреси процедури, що має правильну сигнатуру. VB .NET автоматично обчислює об'єкт по повному імені процедури. Команда створення екземпляра виглядає так:

    adel egate = Addressof test.TestSub

    Компілятор VB .NET розуміє, що делегат створюється для об'єкту test. Також можна скористатися ключовим словом New, проте це робиться рідко, оскільки New неявно викликається в першій формі:

    adelegate = New Stringsubdelegate(Addressof test.TestSub)

    Після того, як делегат буде створений, інкапсульована в нім процедура викликається методом Invoke класу Delegate, як в наступному фрагменті:

    Sub Main( )

    Dim test As New Classforstri ngsubdelegate()

    Dim adelegate As Stringsubdelegate

    adelegate = Addressof test.TestSub

    adelegate.Invoke( "Hello" )

    Console. Readlineb

    End Sub

    Насправді використовувати Invoke необов'язково — досить передати делегатові потрібні параметри. VB .NET зрозуміє команду adelegate(" Hello"), яка виглядає значно простішим.

    У цьому неважко переконатися, проглядаючи отриманий IL-код за допомогою програми ILDASM.

    Погодитеся, такий спосіб виводу в консольному вікні рядка «Hellohello» виглядає декілька незвично!

    Втім, «якщо це і безумство, то у своєму роді послідовне». Припустимо, ви вирішили удосконалити свій клас, щоб замість простого виведення тексту в консольному вікні на екрані з'являлося вікно повідомлення. Для цього досить внести зміни, виділені жирним шрифтом в наступному лістингу:

    Module Modulel

    Public Delegate Sub Stringsubdelegate(Byval astring As String)

    Sub Main()

    Dim test As New Classforstringsubdelegate()

    Dim adelegate As Stringsubdelegate

    adelegate - Addressof test.TestMsgBox

    adelegate("Hello")

    Console. Readline()

    End Sub

    Class Classforstringsubdelegate

    ' Використовувати конструктор за умовчанням

    Public Sub Testsub(Byval astring As String)

    Console.WriteLine(astring Sastring)

    End Sub

    Public Sub Testmsgbox(Byval astring As String)

    Msgbox(astring &aString)

    End Sub

    End Class End Module

    Оскільки для делегата важлива тільки сигнатура інкапсульованого методу, він легко «перемикається» на інший метод. Потрібно було створити нову версію для виведення інформації у вікні відладки (замість консолі і вікна повідомлення)? Досить внести декілька змін делегат і додати в клас функцію, що інкапсулюється делегатом.

    Найважливіша особливість делегатів полягає в тому, що пов'язання з методом проводиться на стадії виконання. Таким чином, делегати у поєднанні з явним або неявним викликом методу Invoke по своїх можливостях значно перевершують функцію Vb6 Callbyname.

     




    :: Наша кнопка ::

    Отримати код:

    Підтримайте наш сайт і розмістіть нашу кнопку на своєму ресурсі.


    :: Реклама ::

    Скачати безкоштовно програму Microsoft Front Page 2003


    :: Посилання ::

    -


     

     

     


    Copyright ©