Raising Shared Events

Team-Fly    

 
Visual Basic .NET Unleashed
By Paul Kimmel
Table of Contents
Chapter 11.  Shared Members

Raising Shared Events

Chapters 8 and 9 explained dynamic programming afforded to us by events and event handlers, all falling under the auspices of the Delegate class.

Keep in mind that RaiseEvent incurs no penalty if there are no respondents. If you write your code to invoke a specific method, at runtime you are stuck with the behavior described by that respondent. However, if you define an event and raise the event, any respondent can answer the event. Consider the revised code from Listing 11.9, shown in Listing 11.10, that demonstrates using a fixed respondent to indicate to the consumer of HasOverloaded that a Print method was invoked. (Parts of the original code from Listing 11.9 were concealed with code outlining to shorten the listing.)

Caution

Listing 11.10 demonstrates code that is too dependent on the existence of a specific form, Form1. Avoid writing code that relies on a specific object instance.


Listing 11.10 A shared method talking to an instance of a form
  1:  Public Class Form1  2:  Inherits System.Windows.Forms.Form  3:   4:  [ Windows Form Designer generated code ]  5:   6:  Private Sub Button1_Click(ByVal sender As System.Object, _  7:  ByVal e As System.EventArgs) Handles Button1.Click  8:   9:  HasOverloaded.Print("Hello World!")  10:  [...]  11:   12:  End Sub  13:   14:  Public Sub Print(ByVal Value As Object)  15:  Text = "Print: " & Value  16:  End Sub  17:   18:  Private Sub Form1_Load(ByVal sender As System.Object, _  19:  ByVal e As System.EventArgs) Handles MyBase.Load  20:   21:  HasOverloaded.AForm = Me  22:   23:  End Sub  24:   25:  End Class  26:   27:  Public Class HasOverloaded  28:   29:  Public Shared AForm As Form1  30:   31:  Overloads Shared Sub Print(ByVal Text As String)  32:  AForm.Print(Text)  33:  Debug.WriteLine(Text)  34:  End Sub  35:   36:  [...]  37:   38:  End Class 

HasOverloaded uses a shared field, AForm on line 29, to obtain a reference to an instance of Form1. Form1's OnLoad event handler, defined on lines 18 through 23, initializes the shared reference in HasOverloaded. Functionally, and to a limited degree, this code works, but as a rule it's considered bad form. Although aggregation, inheritance, and references are a good thing in general, the reference to Form1 makes HasOverloaded brittle. In essence, the instance of the form breaches the invisible bubble of encapsulation, which should be avoided. Consider what happens to HasOverloaded if Form1 is destroyed . The Print method on line 31 is no longer valid. Again, what happens if Form1 is given a better name ? Again, HasOverloaded.Print (line 31) is invalid.

A preferable alternative in this instance is to use a shared event to promote the interaction to the class interface level. The end result (shown in Listing 11.11) is valid code regardless of whether or not Form1 exists or is renamed because the interaction happens at the class interfacealong the edges described by the public membersinstead of inside the methods .

Listing 11.11 Using a shared event to facilitate interactions with class methods
  1:  Public Class Form1  2:  Inherits System.Windows.Forms.Form  3:   4:  [ Windows Form Designer generated code ]  5:   6:  Private Sub Button1_Click(ByVal sender As System.Object, _  7:  ByVal e As System.EventArgs) Handles Button1.Click  8:   9:  HasOverloaded.Print("Hello World!")  10:  [...]  11:   12:  End Sub  13:   14:  Private Sub OnPrint(ByVal Value As Object)  15:  Text = "OnPrint: " & Value  16:  End Sub  17:   18:  Private Sub Form1_Load(ByVal sender As System.Object, _  19:  ByVal e As System.EventArgs) Handles MyBase.Load  20:   21:  AddHandler HasOverloaded.OnPrint, AddressOf OnPrint  22:   23:  End Sub  24:   25:  End Class  26:   27:  Public Class HasOverloaded  28:   29:  Public Shared Event OnPrint(ByVal Value As Object)  30:   31:  Overloads Shared Sub Print(ByVal Text As String)  32:  RaiseEvent OnPrint(Text)  33:  Debug.WriteLine(Text)  34:  End Sub  35:   36:  [...]  37:   38:  End Class 

The revised listing adds the handler Form1.OnPrint to the implicit Delegate defined by the shared event on line 29 in the HasOverloaded class. Line 32 simply raises the event and is indifferent to the specific recipients, or even if there are recipients. What you don't see is that the RaiseEvent statement on line 32 checks an invocation list and sends the event to respondents, but it works correctly whether there are respondents or not.

An additional benefit of using the public Shared event is that other objects can implement OnPrint handlers and add themselves to the invocation list of the Delegate in HasOverloaded. This minor revision might seem trivial, but these small changes in implementation mean the difference between flexible, robust, and loosely coupled code (as in Listing 11.11) and brittle, unmanageable, and tightly coupled code (as in Listing 11.10). That is all the difference in the world.


Team-Fly    
Top
 


Visual BasicR. NET Unleashed
Visual BasicR. NET Unleashed
ISBN: N/A
EAN: N/A
Year: 2001
Pages: 222

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net