:: Меню ::

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

    :: Друзі ::

     
     

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

    = =

     

     

     

     

    Групові делегати

    У приведених вище прикладах в делегатові інкапсулювалася адреса однієї функції або процедури. Нерідко в делегатах потрібно інкапсулювати відразу декілька процедур (інкапсуляція декількох функцій особливого сенсу не має — яким має бути повертане значення?). Подібні делегати називаються груповими (multicast) і реалізуються у вигляді делегата, що містить декілька однотипних делегатів. За наявності групового делегата всі інкапсульовані процедури викликаються одним методом Invoke, причому це відбувається відповідно до порядку занесення їх делегатів в груповий делегат.

    Щоб створити груповий делегат, слід об'єднати мінімум двох делегатів одного типу і привласнити результат змінної того ж типу. Завдання вирішується статичним методом Combine класу System.Delegate, який повертає новий делегат.

    Допустимо, firstdel і secdel — екземпляри класу Mymulticastdelegate. Наступна команда об'єднує firstdel і secdel в груповий делегат, що зберігається в

    firstdel: firstdel =System.Delegate.Combine(firstdel,secdel)

    Нижче приведено просте застосування, об'єднуюче адреси декількох функцій в груповому делегатові:

    1 Option Strict On

    2 Module Modulel

    3 Sub Main()

    4 Console.WriteLine("Calling delegate function...")

    5 Registerdelegate(Addressof Callbackhandlerl)

    6 Registerdelegate(Addressof Callbackhandler2)

    7 Call Delegates ()

    8 Console.WriteLine(

    9 "Finished calling.delegate function...")

    10 Console.ReadLine()

    11 End Sub

    12 Public Sub Callbackhandlerhbyval lngval As RETURNJALUES)

    13 Console.WriteLine("Callback 1 returned " & Ingval)

    14 End Sub

    15 Public Sub Callbackhandler2(Byvallngval As RETURNJALUES)

    16 Console.WriteLine("Callback 2 returned " & Ingval)

    17 End Sub

    18 End Module

    19 Module Module2

    20 Public Delegate Sub Callbackfunc(Byvallngvalas Return_values)

    21 Private m_cbfunc As Callbackfunc

    22 Public Enum Return_values

    23 Value_success

    24 Value_failure

    25 End Enum

    26 Public Sub Registerdelegate(Byref cbfunc As Callbackfunc)

    27 m_cbfunc = Ctype(System.Delegate.Combine(_

    28 m_cbfunc.cbFunc).CallBackFunc)

    29 End Sub

    30 Public Sub Call Delegates ()

    31 Dim Ingcounter As Long = 0

    32 ' Викликати процедури через делегата

    33 ' і повернути ознаку успішного виклику

    34 m_cbfunc(RETURN VALUES.VALUE_SUCCESS)

    35 End Sub

    36 End Module

    У рядках 5 і 6 викликається процедура модуля Module2 (рядки 26-28), де і відбувається фактична побудова групового делегата. Це можливо завдяки тому, що делегат передається по посиланню, а не за значенням. Звернете увагу на перетворення типу методу Combine до типу делегата в рядку 27. Безпосередній виклик функцій групового делегата відбувається в рядках 30-35. Всім зареєстрованим функціям передається значення перераховуваного типу RETURNJALUES . Value_success. Результат виконання програми показаний на малюнку.


    Групові делегати як члени класів

    У попередньому прикладі всі модулі мають доступ до всіх функцій решти модулів. Таку архітектуру не можна визнати вдалою — правильніше було б оформити делегат у вигляді члена класу, ніж у вигляді відкритого об'єкту. Це дозволить виконати перед його створенням перевірку, аналогічну тій, яка виконується для інших членів класу. Нижче приведений злегка змінений варіант предиду-

    щів архітектури, де перед доповненням групового делегата новими функціями виконується перевірка (у даному прикладі — вельми тривіальна). Відповідний фрагмент виділений жирним шрифтом:

    Option Strict On

    Public Class Delegateserver

    Public Delegate Sub Clientcallback(Byval Ingval As Long)

    Private m_clients As Clientcallback

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

    Public Sub Registerdelegate(Byval adelegate As

    Clientcallback.ByVal dolt As Boolean)

    ' Зазвичай тут виконується повноцінна перевірка.

    ' У даному прикладі функція зворотного виклику реєструється

    ' лише в тому випадку, якщо другий параметр рівний

    True. If dolt Then

    m_clients = Ctype(System.Delegate.Combine(m_ Clients.aDelegate)._

    Clientcallback)

    End If

    End Sub

    Public Sub Callclients(Byval Ingval As Long)

    m_clients( Ingval)

    End Sub

    End Class

    Module Modulel

    Sub Main()

    Dim delsrv As New Delegateserver()

    delsrv.RegisterDelegate(Addressof Delegatecallbackhandlerl.True)

    ' He викликається - другий параметр рівний False!

    delsrv.RegisterDelegate(Addressof Delegatecal1backhandler2.False)

    ' Ініціювати звернення до клієнтів

    delsrv.CallClients(125)

    Console.WriteLine("Press enter to end.")

    Console.ReadLine()

    End Sub

    Public Sub Delegatecallbackhandlerkbyvalingval As Long)

    System.Console.WriteLine("Delegateca11backhandlerl cal1ed")

    End Sub

    Public Sub Delegatecallbackhandler2(Byval Ingval As Long)

    System.Console.Wri teline("Delegatecal1backhandler2 cal1ed")

    End Sub

    End Module

    Делегати і події

    Ми розглянули різноманітні приклади використання делегатів, проте жоден з них не мав відношення до обробки подій. Втім, зв'язок між делегатами і подіями в VB .NET вельми проста. При кожному використанні скороченого синтаксису обробки подій, описаного в першій половині глави, VB .NET непомітно визначає клас делегата для обробки події, а команда Addressof створює екземпляр делегата для цього обробника. Наприклад, наступні два рядки еквівалентні (Eventhandler — ім'я неявно визначуваного делегата):

    Addhandler Buttonl.Click.AddressOf Me.Buttonl_Click

    Addhandler Buttonl.Click.New Eventhandler(Addressof Buttonl Click)

    По суті, кожна подія відповідає делегатові наступного вигляду:

    Public Delegate Event (sender As Object.evt As Eventargs)

    Виклик Raiseevent просто приводить до виклику Invoke для делегата, що автоматично згенерував.

     




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

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

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


    :: Реклама ::

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


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

    -


     

     

     


    Copyright ©