Do event handlers need to exactly match the event signature?
I would like to do something like the following:
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
However, it seems to be invalid syntax, as the signature of OnEvt1OrEvt2 doesn't match that of Evt2.
Is there any way to achieve this?
Edit: The above code seems to work fine for everyone but me, but it doesn't compile for me in VS2005 SP1.
The error message is something like:
Error BC31029: The method 'Private Sub OnEvt1OrEvt2(c As WindowsApplication1.c1)' can not handle the event 'Public Event Evt2(c As WindowsApplication1.c2)' because the signatures do not match.
Edit 2:
I have found this in msdn, vb-related:
http://msdn.microsoft.com/en-us/library/ms973905.aspx
The code in the Form Load assigns values to the Name property of the three Bucket objects. It also calls Ad开发者_如何学PythondHandler to direct all of the Overflowing events to the HandleOverflow procedure. As you can see, a single event handler can handle multiple events, as long as all of the events have compatible argument lists.
(...)
Copyright © 2002 Informant Communications Group and Microsoft Corporation
(Emphasis mine)
No word about what two "compatible argument lists" exactly are, though.
Edit 3:
OK, I found it: http://msdn.microsoft.com/en-us/library/ms364068%28v=vs.80%29.aspx#vb9overview_topic10
Relaxed Delegates
When creating a delegate using AddressOf or Handles in Visual Basic 8.0, one of the methods targeted for binding to the delegate identifier must exactly match the signature of the delegate's type.
It was added in VB9.
Your code compiles for me, from the command line.
I don't know when the feature appeared in VB, but in C# this was one of the differences between C# 1 and C# 2. Delegates can be created from methods with compatible signatures rather than requiring an exact match.
EDIT: Given your question edit, it looks like this is an issue with VB8 / VS2005. It works for me with both the VS2008 and VS2010 compilers (VB9 and VB10 respectively).
In order for this to work, you would need to define your event such that the parameter is passed as type Object, and then perform a casting operation within the event handler.
OR you could define an interface common to both C1 and C2, and use that as the parameter. You could then either use the reference "as-is" if the methods defined on the interface are suitable, or you would once again find yourself performing a casting operation.
Note that if you define an interface with the common methods, and if these common methods are all that is required for use by the event handler, then you do not need to perform any sort of "TypeOf" determination in order to handle the event.
All that said, I know that it is best, if possible, to follow the Event signature standard established within .NET wherever possible:
Public Event SomethingHappened(ByVal Sender as Object, byVal e As System.EventArgs)
It looks to me like you might create a class (or classes) which inherits from System.EventArgs, and then define a custom property to access your custom parameter. This way, you can still pass a reference to the client object in the Sender
parameter, and then access your custom parameter thus:
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
I'm a C# user and am a lousy VB.NET-reader. Automatic online conversion utilities failed to help me with your code, so I'm writing from scratch. There are two thoughts that I would like to implement at every event invocation I see:
- Use EventHandler<T> instead of declaring custom delegates.
Have your base class derive from 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 {}
}
After actually creating a VB.NET console application to try this out, I found out that just removing your "..." in your code compiles, so you basically have a working code snippet already... What's the problem?
精彩评论