RELAXED DELEGATES

If you assign a variable to the value in a variable of a different type, Visual Basic automatically converts the value into the correct type under some circumstances. If you set a Single variable equal to an Integer variable, Visual Basic automatically converts the Integer into a Single.

If Option Strict is off, you can also do the reverse: If you assign an Integer variable equal to a Single variable, Visual Basic converts the Single into an Integer (if it can).

In a similar manner, relaxed delegates let Visual Basic convert method parameters from one data type to another under certain circumstances. If the code invokes a subroutine by using a delegate, Visual Basic tries to convert parameters when it can. Probably the easiest way to understand how this works is to consider an example.

The following code declares a delegate type named TestDelegate. Methods that match this delegate should be subroutines that take a Control as a parameter.

' Declare the delegate type.
Private Delegate Sub TestDelegate(ctl As Control)

The following code defines three subroutines that take parameters of different types. The first takes an Object as a parameter, the second takes a TextBox, and the third takes no parameters. Note that the first subroutine cannot work if Option Strict is on. Option Strict disallows late binding, so the code cannot use a Text property provided by a generic Object.

' A more general parameter type.
Private Sub Test1(obj As Object)
    obj.Text = "Test1" ' Needs Option Strict off.
End Sub
 
' A more specific parameter type.
Private Sub Test2(text_box As TextBox)
    text_box.Text = "Test2"
End Sub
 
' Parameter omitted.
Private Sub Test3()
    txtField3.Text = "Test3"
End Sub

The following code declares three variables of the TestDelegate type and sets them equal to the addresses of the three test subroutines:

' Make variables of the delegate type hold references to the subroutines.
Private Sub1 As TestDelegate = AddressOf Test1
Private Sub2 As TestDelegate = AddressOf Test2 ' Needs Option Strict off.
Private Sub3 As TestDelegate = AddressOf Test3

The first assignment works even though subroutine Test1 does not exactly match the delegate type. Subroutine Test1 takes an Object as a parameter and TestDelegate takes a Control as a parameter. When Visual Basic invokes the Sub1 variable, it will pass the subroutine a Control object as a parameter because Sub1 has type TestDelegate, and that type takes a Control as a parameter. A Control is a type of Object, so Visual Basic can safely pass a Control in place of an Object parameter. That allows the code assigning Sub1 to the address of subroutine Test1 to work.

The second line of code that assigns variable Sub2 to subroutine Test2 works only if Option Strict is off. When Visual Basic invokes the Sub2 variable, it will pass the subroutine a Control object as a parameter because Sub1 has type TestDelegate, and that type takes a Control as a parameter. Subroutine Test2 takes a TextBox as a parameter, and not every Control is a TextBox. That means at design time Visual Basic cannot tell whether it can safely invoke the Sub2 delegate so, if Option Strict is on, Visual Basic flags this assignment as an error. If Option Strict is off, Visual Basic allows the assignment, although the program will crash if it tries to pass a control that is not a TextBox into Sub2 at run time.


STRICTLY SPEAKING
This is similar to setting a TextBox variable equal to the value in a Control variable. If Option Strict is on, Visual Basic will not allow that assignment.

The final assignment sets variable Sub3 to the address of subroutine Test3. Subroutine Test3 takes no parameters. This is a special case that Visual Basic allows: If the method does not need to use the parameters specified by the delegate, it can omit its parameters. Note that the method must omit all or none of the parameters; it cannot omit some and not others.

The following code invokes the subroutines pointed to by the three TestDelegate variables, passing each a reference to a different TextBox. Sub1 treats txtField1 as an Object, Sub2 treats txtField2 as a TextBox, and Sub3 ignores its parameter completely.

Sub1(txtField1)
Sub2(txtField2)
Sub3(txtField3)
' Test3(txtField3) ' This doesn't work.

The final line of code, that invokes subroutine Test3 directly, doesn’t work. Omitting the parameter list from a method only works if you access the method from a delegate. If you call the method directly, the parameter list must match the one declared for the method.

Example program RelaxedDelegates, which is available for download on the book’s website, demonstrates this code.

All of these relaxed delegate rules are somewhat confusing. They give you a little more flexibility, but they can make the code a lot more confusing. You may wonder why you should bother. In fact, if you use delegates such as those shown in this example, you might want to avoid using relaxed delegates to keep the code easier to understand.

These rules also apply to event handlers, and in that context they are much more useful. They let you change an event handler’s parameter types to make them more general or more specific, or to omit them entirely.

The following code shows a simple, standard Button Click event handler. It takes two parameters of types Object and EventArgs. In this example, the code reads a text file into a text box.

Private Sub btnLoad_Click(sender As Object,
 ByVal e As EventArgs) Handles btnLoad.Click
    txtContents.Text = File.ReadAllText(txtFile.Text)
End Sub

Many event handlers must deal explicitly with the control that raised their event. In that case, the first thing the event handler usually does is convert the generic sender parameter from an Object into a more specific control type.

The following code defines a Button Click event handler similar to the previous one but this one declares its sender parameter to be of type Button. This works as long as the event is actually raised by a Button so the sender parameter really is a button. If you were to attach this event handler to a TextBox’s TextChanged event, the program would crash when Visual Basic tried to convert the TextBox into a Button when it raises the event.

' Needs Option Strict off.
Private Sub btnLoad2_Click(btn As Button,
 ByVal e As Object) Handles btnLoad2.Click
    txtContents.Text = File.ReadAllText(txtFile.Text)
End Sub

Note that this version requires Option Strict off. If Option Strict is on, Visual Basic will not allow this subroutine to handle a Button’s Click event. This is similar to the way Option Strict prevents you from setting a Button variable equal to a generic Object variable.

The previous code declares its parameters to have a more restrictive type than those passed into it by the control raising the event. You can also make the parameters more general. You could declare the e parameter to be of type Object instead of EventArgs. Usually, that doesn’t help you much. It could be useful if you want to use the same event handler to catch different kinds of events that provide different types of arguments, but it’s hard to imagine a really good example where that wouldn’t be confusing.

A more common situation is where the event handler ignores its parameters completely. Usually each Button has a separate Click event handler so you don’t need to look at the parameters to figure out which button was clicked.

The following code defines a Button Click event handler that takes no parameters. When the user clicks the btnLoad3 Button, Visual Basic doesn’t pass the event handler any parameters. This code is easier to read than the previous versions, partly because the Sub statement fits all on one line.

Private Sub btnLoad3_Click() Handles btnLoad3.Click
    txtContents.Text = File.ReadAllText(txtFile.Text)
End Sub

Example program RelaxedEventHandlers, which is available for download on the book’s website, demonstrates relaxed event handlers.

Relaxed delegates may add more confusion than they’re worth if you use delegate variables, but they can be useful for simplifying event handlers. Declaring parameters with a more specific type (for example, Button instead of Object) can make the code easier to write and understand, although it has the large drawback of requiring Option Strict off. Omitting parameters when you don’t need them is an even better technique. It simplifies the code without forcing you to turn Option Strict off.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.48.78