Должны ли обработчики событий точно соответствовать сигнатуре события? - PullRequest
1 голос
/ 27 января 2011

Я хотел бы сделать что-то вроде следующего:

Public Class Form1
    Public Event Evt1(ByVal c As c1)
    Public Event Evt2(ByVal c As c2)

    Private Sub OnEvt1OrEvt2(ByVal c As c1) Handles Me.Evt1, Me.Evt2
    End Sub 
End Class

Public Class c1
End Class

Public Class c2
    Inherits c1
End Class

Однако, похоже, синтаксис неверен, так как подпись OnEvt1OrEvt2 не совпадает с подписью Evt2.

Есть ли способ добиться этого?

Редактировать: Вышеприведенный код, кажется, работает хорошо для всех, кроме меня, но он не компилируется для меня в VS2005 SP1.

Сообщение об ошибке выглядит примерно так:

Ошибка BC31029: метод 'Private Sub OnEvt1OrEvt2 (c As WindowsApplication1.c1) 'не может справиться мероприятие 'Public Event Evt2 (c As WindowsApplication1.c2) 'потому что подписи не совпадают.

Редактировать 2:

Я нашел это в MSDN, В.Б связанные с:

http://msdn.microsoft.com/en-us/library/ms973905.aspx

Код в форме загрузки присваивает значения для свойства Name три объекта Bucket. Это также вызывает AddHandler, чтобы направить все Переполнение событий в Процедура HandleOverflow. Как вы можете видите, один обработчик событий может обрабатывать несколько событий, пока все события имеют совместимых списков аргументов.

(...)

Copyright © 2002 Informant Коммуникационная группа и Microsoft Корпорация

(Акцент мой)

Нет слов о том, что именно представляют собой два "списка совместимых аргументов".

Редактировать 3:

ОК, я нашел это: http://msdn.microsoft.com/en-us/library/ms364068%28v=vs.80%29.aspx#vb9overview_topic10

Расслабленные делегаты

При создании делегата с использованием AddressOf или дескрипторы в Visual Basic 8.0, один из методов, предназначенных для привязки к идентификатору делегата должен точно соответствовать подписи тип делегата.

Добавлено в VB9.

Ответы [ 3 ]

2 голосов
/ 27 января 2011

Ваш код компилируется для меня из командной строки.

Я не знаю, когда эта функция появилась в VB, но в C # это было одним из различий между C # 1 и C # 2. Делегаты могут быть созданы из методов с совместимыми сигнатурами, вместо точное совпадение.

РЕДАКТИРОВАТЬ: Учитывая ваш вопрос редактирования, похоже, что это проблема с VB8 / VS2005. Это работает для меня с компиляторами VS2008 и VS2010 (VB9 и VB10 соответственно).

1 голос
/ 27 января 2011

Чтобы это работало, вам нужно определить ваше событие так, чтобы параметр передавался как тип Object, а затем выполнить операцию приведения в обработчике события.

ИЛИ вы можете определить интерфейс, общий для C1 и C2, и использовать его в качестве параметра.Затем вы можете использовать ссылку «как есть», если методы, определенные в интерфейсе, подходят, или вы снова окажетесь в операции приведения.

Обратите внимание, что если вы определяете интерфейс с помощью общих методов, и если эти общие методы - это все, что требуется для использования обработчиком событий, то вам не нужно выполнять какое-либо определение "TypeOf" вДля обработки события.

Все это говорит о том, что я знаю, что лучше, если это возможно, следовать везде, где это возможно, стандарту подписи событий, установленному в .NET:класс (или классы), который наследуется от System.EventArgs, а затем определяет настраиваемое свойство для доступа к вашему настраиваемому параметру.Таким образом, вы все равно можете передать ссылку на объект клиента в параметре Sender, а затем получить доступ к своему пользовательскому параметру следующим образом:

Public Class MyCustomEventArgs
    Inherits System.EventArgs

    Private _MyCustomInterface As ICustomInterface

    Public Property Myproperty As ICustomInterface
        Get As ICustomInterface
            Return _MyCustomInterface
        End Get
        Let(ByVal value As ICustomInterface)
            _MyCustomInterface = value
        End Let
    End Property
End Class

Public Sub HandleMyEvent(ByVal Sender As Object, byVal e As MyCustomEventArgs) Handles MyEvent
    Dim MyCustom Interface As ICustomInterface
    MyCustominterface = e.TheCustominterface
    MyCustominterface.DoSomething
End Sub
1 голос
/ 27 января 2011

Я пользователь C # и паршивый читатель VB.NET.Утилиты автоматического онлайн-конвертации не помогли мне с вашим кодом, поэтому я пишу с нуля.Есть две мысли, которые я хотел бы реализовать при каждом вызове события, которое я вижу:

  1. Используйте EventHandler вместо объявления пользовательских делегатов.
  2. Имейте свой базовый класспроизводные от EventArgs:

    public static void Main() {
        BaseEvent += OnSomething;
        DerivedEvent += OnSomething;
    }
    
    public static void OnSomething(Object sender, MyBase args) {
        // Awesome!
    }
    
    public static event EventHandler<MyBase> BaseEvent;
    public static event EventHandler<MyDerived> DerivedEvent;
    
    public class MyBase : EventArgs {}
    public class MyDerived : MyBase {}
    

    }

После создания консольного приложения VB.NET для этого я обнаружил, что просто удаляю "... "в вашем коде компилируется, так что у вас уже есть рабочий фрагмент кода ... В чем проблема?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...