I'm going to start this post off with a small rant on two things. First its the lack of sample code in VB for those of us working with .net 3.5 technologies. Seriously, it sucks. I appreciate those who put up code samples and of course they are going to do so in the language of their choice, but when its MSFT and their employees not giving us VB code it is frustrating.
Second, I think MSFT needs to keep C# and VB compatible which they are mostly, but not completely. When converting code I run into a few problematic spots. One is with anonomous delegates. Personally I think that reading and following code with anonymous delegates is atrocious. It just doesn't seem to make sense to me how code can be executing asynchronously in the middle of a function without tha function being active. I just don't like it. However, it does allow a scenario that is useful: you can utilize local variables in your inline anonymous delegate and all the state is maintained. There is no way to do this intrinsicly in VB.
Here is an example in C# (psuedo C# because I'm winging it):
private void Main() {
mySub(1, btn1);
mySub(2, btn2);
mySub(3, btn3);
}
private void mySub (int i, button button1) {
button1.click +=
delegate(object sender, EventArgs e)
{
myRoutine(i);
}
}
private void myRoutine(int i){
messagebox(i);
}
The interesting thing is that when btn1 is clicked then 1 will display in the messagebox, when btn2 is clicked 2 will display in the messagebox and when btn3 is clicked 3 will display in the messagebox. IOW the state of the object i is maintained when the anonymous delegate is run for that particular instance of mySub.
How can one convert this to VB which doesn't support anonymous delegates? At first glance you may just make a module level variable to store the value of i, add an event handler using addhandler button1.click, addressof myRoutine, then make myRoutine use that module level declaration. That will not work, in the example above you would get the value "3" returned for all 3 of the buttons because th last call to mySub would set that module level variable.
Fortunately the solution is very simple, just use a private class that contains the state of any variables you want to maintain along with the function for the event handler. Here we go in VB:
private sub main()
mySub(1, btn1)
mySub(2, btn2)
mySub(3, btn3)
end sub
private class btnState
public i as integer
public sub click(sender as object, e as system.eventargs)
msgbox(i)
end sub
end class
private sub mySub(i as integer, button1 as button)
dim objState as new btnState
objState.i = i
addhandler button1.click, addressof myObj.Click
end sub
The object now contains the state of i as needed and also contains the delegated subroutine that will be called whenever a button is clicked. Since each instance contains its own version of "i" you get the same results as you would from the C# code above!
To finish my rant, I really wish that they would add the missing pieces of VB that C# has so that code conversions would be easier to do. If not, PLEASE GIVE US MORE VB SAMPLES!
Hope this is helpful!
Sean