Polymorphism in VB.NET via Late Binding prohibits the use of events, workaround?

I am working on developing an application that talks about the USB sensor family. I created a basic implementation that uses the Sensor class. The class contains events and methods that allow you to interact with the sensor (there is also a multi-threaded task processor, but I will go with a simple example).

My problem is that this simple proof of an example concept works fine, but now I need to expand the application to support the entire sensor family. To do this, I created the BaseSensor class with all the appropriate methods and events, and then created several subclasses such as SensorA, SensorB and SensorC, which are all inherent in BaseSensor.

This seemed like a good use of polymorphism, so I created a Shared function in BaseSensor called Initialize that performs the initial USB connection and returns the correct object depending on the type of sensor (SensorA, SensorB, SensorC). This works great, but it seems that I cannot find a way to correctly declare a With Events object. See Sample Code for my delicacy.

Attempt 1:

Public Class Form1 Dim WithEvents oBaseClass As BaseClass Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load oBaseClass = New ExtendedClass oBaseClass.Test() 'This doesn't work because the object was type casted. End Sub Private Sub TestEventHdlr() Handles oBaseClass.TestEvent MsgBox("Event Fired") End Sub End Class Public Class BaseClass Public Event TestEvent() End Class Public Class ExtendedClass Inherits BaseClass Public Sub Test() MsgBox("Test") End Sub End Class 

Attempt 2:

 Public Class Form1 Dim WithEvents oBaseClass 'This doesn't work. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load oBaseClass = New ExtendedClass oBaseClass.Test() End Sub Private Sub TestEventHdlr() Handles oBaseClass.TestEvent MsgBox("Event Fired") End Sub End Class Public Class BaseClass Public Event TestEvent() End Class Public Class ExtendedClass Inherits BaseClass Public Sub Test() MsgBox("Test") End Sub End Class 

Something is missing for me. How do I proceed?

+1
source share
4 answers

WithEvents cannot be late. You need to declare your field as a type. If all of the objects used in this scenario come from a common base, you will do yourself a great deal in linking late binding. Throw when necessary, and declare virtual (redefinable) methods to implement your polymorphism.

 Public Class Form1 Dim WithEvents oBaseClass As BaseClass 'Early bound' Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load oBaseClass = New ExtendedClass DirectCast(oBaseClass, ExtendedClass).Test() 'Casting to call a method' End Sub Private Sub TestEventHdlr() Handles oBaseClass.TestEvent MsgBox("Event Fired") End Sub End Class Public Class BaseClass Public Event TestEvent() End Class Public Class ExtendedClass Inherits BaseClass Public Sub Test() MsgBox("Test") End Sub End Class 
+3
source

Is this what you are looking for?

 Public Class Form1 Private WithEvents oBaseClass As ExtendedClass Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load oBaseClass = New ExtendedClass oBaseClass.Test() End Sub Private Sub TestEventHdlr() Handles oBaseClass.TestEvent MsgBox("Event Fired") End Sub End Class Public Class BaseClass Public Event TestEvent() Friend Sub raiseTestEvent() RaiseEvent TestEvent() End Sub End Class Public Class ExtendedClass Inherits BaseClass Public Sub Test() MsgBox("Test") raiseTestEvent() End Sub End Class 

If not, you need to create an interface and declare it in your form and set the appropriate class for it in form_load

0
source

Slightly adjusted to raise an event, if you want an example of this, slightly modified the event and suggested a slightly different approach.

 Public Class Form1 Dim oBaseClass As BaseClass 'Early bound' Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load oBaseClass = New ExtendedClass If TypeOf oBaseClass Is BaseClass Then AddHandler DirectCast(oBaseClass, BaseClass).TestEvent, AddressOf TestEventHdlr End If oBaseClass.Test() End Sub Private Sub TestEventHdlr() MsgBox("Event Fired") End Sub End Class Public Class BaseClass Public Event TestEvent() Public Overridable Sub Test() RaiseEvent TestEvent() End Sub End Class Public Class ExtendedClass Inherits BaseClass Public Overrides Sub Test() MyBase.Test() MsgBox("Test") End Sub End Class 
0
source

Depending on the type of behavior you are looking for for the model, you may need to use interfaces instead of Inheritence or a mixture of them. Instead of having a base object that defines the event, define interfaces-based behavior or functions and implement the ones equivalent to your extended class

It annoyed me too much, but it made me find out about them, and since you can implement several types of interfaces for each object, it is ultimately very flexible.

One tip: think about the contents of the interface first. Although VS automatically inserts the stubs method / property for you, if you later change the interface definition, this is a manual effort to update implementations.

Simon

0
source

Source: https://habr.com/ru/post/1432783/


All Articles