VB.NET Why is this subroutine declared this way?
VB.NET 2010, .NET 4
I have a basic question: I have a subroutine that I found somewhere online declared thusly:
Public Sub MyFunction(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of T)) ...
I'开发者_运维知识库m wondering about the (Of T As Control) part of the declaration after the sub's name. I see that T is used later in specifying the type of Control and in Action(Of T), but why is it done this way instead of just doing:
Public Sub MyFunction(ByVal Control As Control, ByVal Action As Action(Of Control)) ...
What does that part after the sub's name mean? What is its purpose? Thanks a lot and sorry for my ignorance.
That is VB.NET's generic method declaration syntax:
A generic type is a single programming element that adapts to perform the same functionality for a variety of data types. When you define a generic class or procedure, you do not have to define a separate version for each data type for which you might want to perform that functionality.
An analogy is a screwdriver set with removable heads. You inspect the screw you need to turn and select the correct head for that screw (slotted, crossed, starred). Once you insert the correct head in the screwdriver handle, you perform the exact same function with the screwdriver, namely turning the screw.
(Of T) is a generic type parameter, adding As Control constrains the type of T to inherit from Control. You could write the method the second way, but you'd probably end up having to cast the Control to whatever inherited type, within the lambda expression in the Action, or in the body of MyFunction. Generics allow you to avoid that.
For example:
Sub Main()
Dim form As New Form()
Dim textBox As New TextBox
Dim listBox As New ListBox
MyFunction(textBox, Sub(c) c.Text = "Hello")
MyFunction(listBox, Sub(c) c.Items.Add("Hello"))
MyFunction2(textBox, Sub(c) c.Text = "Hello")
MyFunction2(listBox, Sub(c) CType(c, ListBox).Items.Add("Hello"))
End Sub
Public Sub MyFunction(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of T))
Action(Control)
End Sub
Public Sub MyFunction2(ByVal Control As Control, ByVal Action As Action(Of Control))
Action(Control)
End Sub
It doesn't look too valuable in trivial cases, but it's invaluable for more complex cases.
As others have said, it's a constrained generic parameter. But no one has yet addressed this part of your question:
why is it done this way
The answer is in the action. If it were just declared as a Control, you wouldn't be able to do something like this, because not all controls have a .Text property*:
MyFunction(MyTextBox, Function(t) t.Text = "new value" )
The body of the function just needs to know that it's working on a control of some kind, but the Action(Of T) you pass to the function might want to know the actual type of the control.
Yes, all controls do have a .Text property. Let's pretend for a moment that some didn't
精彩评论