Why is VB.Net complaining about a custom event when I haven't defined it as such?
Example
Parent C# code that implements the base class to be inherited:
public class EventGenerator
{
public event EventHandler SomethingHappened;
public void SampleMethod()
{
// Event is invoked without issue.
SomethingHappened?.Invoke(this, new EventArgs());
}
}
Child VB.Net class that inherits the base class and attempts to call the event:
Public Class TestClientClass
Inherits EventGenerator
Public Sub TestRaiseInheritedEvent()
' BC31132
RaiseEvent SomethingHappened()
End Sub
End Class
Further reading
https://learn.microsoft.com/en-us/dotnet/standard/events/ https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/ http://jmcilhinney.blogspot.com/2009/11/defining-and-raising-custom-events.html
CodePudding user response:
It doesn't matter if this is C#, VB.NET, or a combination of both, you simply cannot do this in .NET:
Public Class Foo
Public Event Bar As EventHandler
End Class
Public Class Qaz
Inherits Foo
Private Sub RaiseBarFromQaz()
RaiseEvent Bar(Me, New EventArgs())
End Sub
End Class
It gives me the error: BC30029 Derived classes cannot raise base class events.
The C# version of this error is: CS0070 The event 'Foo.Bar' can only appear on the left hand side of = or -= (except when used from within the type 'Foo')
.
You must include a Protect Sub
/protected void
in the parent class to allow child classes to raise the event.
It looks like this:
Public Class Foo
Public Event Bar As EventHandler
Protected Sub RaiseBarFromFoo()
RaiseEvent Bar(Me, New EventArgs())
End Sub
End Class
Public Class Qaz
Inherits Foo
Private Sub RaiseBarFromQaz()
RaiseBarFromFoo()
End Sub
End Class
Now, the use of Shadow
is bad. Let's see why.
Sub Main
Dim qaz As New Qaz
Dim foo As Foo = qaz
AddHandler foo.Bar, Sub (s, e) Console.WriteLine("Bar")
qaz.RaiseBarFromQaz()
foo.RaiseBarFromFoo()
End Sub
Public Class Foo
Public Event Bar As EventHandler
Public Sub RaiseBarFromFoo()
RaiseEvent Bar(Me, New EventArgs())
End Sub
End Class
Public Class Qaz
Inherits Foo
Public Shadows Event Bar As EventHandler
Public Sub RaiseBarFromQaz()
RaiseEvent Bar(Me, New EventArgs())
End Sub
End Class
When I run this, even though I call RaiseEvent
twice I only get one event raised. Well, in fact both Bar
events are raised once, but the Shadow
makes it that references to Foo
don't see the event in Qaz
.
Let's look at the correct code for this:
Sub Main
Dim qaz As New Qaz
Dim foo As Foo = qaz
AddHandler foo.Bar, Sub(s, e) Console.WriteLine("Bar")
qaz.RaiseBarFromQaz()
foo.RaiseBarFromFoo()
End Sub
Public Class Foo
Public Event Bar As EventHandler
Public Sub RaiseBarFromFoo()
RaiseEvent Bar(Me, New EventArgs())
End Sub
End Class
Public Class Qaz
Inherits Foo
Public Sub RaiseBarFromQaz()
RaiseBarFromFoo()
End Sub
End Class
Running that gets two Bar
written to the console. It works as expected.