Home > other >  VB.Net BC31132 error when trying to raise the event of a parent class
VB.Net BC31132 error when trying to raise the event of a parent class

Time:12-09

Related to: enter image description here

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.

  • Related