what are generic Subs and Functions for?

  • Thread starter Thread starter Urs Eichmann
  • Start date Start date
U

Urs Eichmann

While experimenting with the Feb CTP Edition of VB 2005, I came across
"generic procedures". You can write:

Public Class Foo

Public Sub MySub(Of tDisp As IDisposable)(ByVal vMyParm As Integer)

End Sub


End Class

I know what generic classes are for, but a generic Sub? Does anybody know
why they are here? I found nothing about it in the help, it is just
explained as a valid syntax for the Sub statement.

Urs
 
Urs,
| I know what generic classes are for, but a generic Sub? Does anybody know
| why they are here?
They allow you to define a method (sub or function) that behaves
polymorphically across types. Just as generic classes allow you to define
classes that behave polymorphically across types...

Consider:

' VS.NET 2005 syntax
Public Function IIf(Of T)(ByVal expression As Boolean, _
ByVal truePart As T, ByVal falsePart As T) As T
If expression Then
Return truePart
Else
Return falsePart
End If
End Function

Which allows you to use the above IIf in Whidbey (aka VS.NET 2005, due out
later in 2005) with Option Strict On, without needing
to cast the return value.

Dim x, y, r As Integer
r = IIf(x < y, x, y)

Dim a, b, c As String
r = IIf(a Is Nothing, a, b)

NOTE: VB is able to figure out the types, so IIf(Of Integer) is not
specifically needed...

I can see defining a similar routine for Choose, something like:

' VS.NET 2005 syntax
Public Function Choose(Of T)(ByVal index As Integer, _
ParamArray ByVal choice() As T) As T
Return choice(index-1)
End Function

Again you can use the above Choose with Option Strict On without needing to
cast the return value! (see below)

Dim r As String = Choose(x, "Happy", "Sad", "Indifferent")

I can also see, Min and Max:

' VS.NET 2005 syntax
Public Function Min(Of T As IComparable(Of T))(ByVal value1 As T, ByVal
value2 As T) As T
If value1.CompareTo(value2) <= 0 Then
Return value1
Else
Return value2
End If
End Function

' VS.NET 2005 syntax
Public Function Max(Of T As IComparable(Of T))(ByVal value1 As T, ByVal
value2 As T) As T
If value1.CompareTo(value2) >= 0 Then
Return value1
Else
Return value2
End If
End Function

NOTE: Min & Max need the constraint that says the type given can compare
themselves with others, the IComparable(Of T) prevents boxing...

Dim r As Integer = Min(1, 2)
Dim r As Double = Max(1.5, 2.5)

Hope this helps
Jay




| While experimenting with the Feb CTP Edition of VB 2005, I came across
| "generic procedures". You can write:
|
| Public Class Foo
|
| Public Sub MySub(Of tDisp As IDisposable)(ByVal vMyParm As Integer)
|
| End Sub
|
|
| End Class
|
| I know what generic classes are for, but a generic Sub? Does anybody know
| why they are here? I found nothing about it in the help, it is just
| explained as a valid syntax for the Sub statement.
|
| Urs
|
|
|
|
 
Jay,
Urs,
| I know what generic classes are for, but a generic Sub? Does anybody know
| why they are here?
They allow you to define a method (sub or function) that behaves
polymorphically across types. Just as generic classes allow you to define
classes that behave polymorphically across types...

Consider:

' VS.NET 2005 syntax
Public Function IIf(Of T)(ByVal expression As Boolean, _
ByVal truePart As T, ByVal falsePart As T) As T
If expression Then
Return truePart
Else
Return falsePart
End If
End Function

thanks for the explanation. I guess I can also write

Public Function ToArray(Of T)(vList as IList) As T()
return directcast(vList.ToArray(T),T())
End Function

instead of the horrible

dim a() as MyClass= DirectCast(vList.ToArray(gettype(MyClass)),MyClass())

I use today to convert an IList to an array. Now I guess I can just use

dim a() as MyClass = ToArray(Of MyClass)(vList)

I look forward to it already :-)
NOTE: VB is able to figure out the types, so IIf(Of Integer) is not
specifically needed...

is that new? 2003 doesn't do it
I can see defining a similar routine for Choose, something like:

' VS.NET 2005 syntax
Public Function Choose(Of T)(ByVal index As Integer, _
ParamArray ByVal choice() As T) As T
Return choice(index-1)
End Function

Boah, is somebody still using Choose? :-)

Thanks for your help
Urs
 
Urs,
| Public Function ToArray(Of T)(vList as IList) As T()
| return directcast(vList.ToArray(T),T())
| End Function
I have not tried (I'm in the middle of rebuilding my test machine).

I'm not sure if VB and/or the Framework will allow the DirectCast or not.
There are a number of rules on what is allowed & what is not allowed, I
don't remember them all...

I would mostly expect it would be allowed.

However! As you may know with the new Generic list classes your conversion
is "unneeded". ;-)

| > NOTE: VB is able to figure out the types, so IIf(Of Integer) is not
| > specifically needed...
| is that new? 2003 doesn't do it

Yes its new as Generics are new... it is closely related to overloading
methods. In C# its called Type Inference & is explained here, I don't see
the VB definition.

http://msdn2.microsoft.com/library/twcad0zb(en-us,vs.80).aspx

Here is a VB swap sample (based on the above):

Public Module UtilityModule

Public Sub Swap(Of T)(ByRef lhs As T, ByRef rhs As T)
Dim temp As T
temp = lhs
lhs = rhs
rhs = temp
End Sub

End Module

Then you can call Swap with either:

Dim a As Integer = 1
Dim b As Integer = 2

Swap(Of Integer)(a, b) ' explicitly call Swap(Of Integer)
Swap(a, b) ' implicitly call Swap(Of Integer)
'as Integer was inferred from the parameters.

| Boah, is somebody still using Choose? :-)
I use it where it makes sense to use it! It makes sense to use it where you
have a list of values to choose from. Granted I don't need it very often...
I know in one program I overloaded Choose with a dozen type safe versions,
using Choose(Of T) will reduce it to a single version...

FWIW: I find Choose to be more useful then the Switch function, as its easy
to create a type safe Choose, however its hard (impossible?) to make a type
safe Switch function...

Hope this helps
Jay




| Jay,
|
| > Urs,
| > | I know what generic classes are for, but a generic Sub? Does anybody
know
| > | why they are here?
| > They allow you to define a method (sub or function) that behaves
| > polymorphically across types. Just as generic classes allow you to
define
| > classes that behave polymorphically across types...
| >
| > Consider:
| >
| > ' VS.NET 2005 syntax
| > Public Function IIf(Of T)(ByVal expression As Boolean, _
| > ByVal truePart As T, ByVal falsePart As T) As T
| > If expression Then
| > Return truePart
| > Else
| > Return falsePart
| > End If
| > End Function
|
| thanks for the explanation. I guess I can also write
|
| Public Function ToArray(Of T)(vList as IList) As T()
| return directcast(vList.ToArray(T),T())
| End Function
|
| instead of the horrible
|
| dim a() as MyClass= DirectCast(vList.ToArray(gettype(MyClass)),MyClass())
|
| I use today to convert an IList to an array. Now I guess I can just use
|
| dim a() as MyClass = ToArray(Of MyClass)(vList)
|
| I look forward to it already :-)
|
| >
| > NOTE: VB is able to figure out the types, so IIf(Of Integer) is not
| > specifically needed...
|
| is that new? 2003 doesn't do it
|
| >
| > I can see defining a similar routine for Choose, something like:
| >
| > ' VS.NET 2005 syntax
| > Public Function Choose(Of T)(ByVal index As Integer, _
| > ParamArray ByVal choice() As T) As T
| > Return choice(index-1)
| > End Function
|
| Boah, is somebody still using Choose? :-)
|
| Thanks for your help
| Urs
 
| Boah, is somebody still using Choose? :-)
I use it where it makes sense to use it! It makes sense to use it where you
have a list of values to choose from. Granted I don't need it very often...
I know in one program I overloaded Choose with a dozen type safe versions,
using Choose(Of T) will reduce it to a single version...

FWIW: I find Choose to be more useful then the Switch function, as its easy
to create a type safe Choose, however its hard (impossible?) to make a type
safe Switch function...

I use neither because the tend to become lengthy and spaghetti-like. I
always use Select Case. But this is my personal preference, I guess.

urs
 
Urs,
| I use neither because the tend to become lengthy and spaghetti-like. I
| always use Select Case. But this is my personal preference, I guess.
Odd, Select Case seems to be longer & more "spaghetti-like" then Choose,
especially for the simple cases where I would use choose Choose over Select
Case!

One short & simple line for the Choose
Dim x As Integer = Choose(index, "x", "xxx", "xx", "xxxx")

Where as there are 13 lines for the Select Case.
Dim x As Integer
Select Case index
Case 0
x = "x"
Case 1
x = "xxx"
Case 2
x = "xx"
Case 3
x = "xxxx"
Case Else
Throw New ArgumentOutOfRangeException(...)
End Case

FWIW:

Select Case by itself suggests using the "Replace Condition with
Polymorphism" refactoring
http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html

Both cases (Choose & Select Case) in my example suggests using the
"Substitute Algorithm" refactoring
http://www.refactoring.com/catalog/substituteAlgorithm.html

Hope this helps
Jay

|>
| > | Boah, is somebody still using Choose? :-)
| > I use it where it makes sense to use it! It makes sense to use it where
you
| > have a list of values to choose from. Granted I don't need it very
often...
| > I know in one program I overloaded Choose with a dozen type safe
versions,
| > using Choose(Of T) will reduce it to a single version...
| >
| > FWIW: I find Choose to be more useful then the Switch function, as its
easy
| > to create a type safe Choose, however its hard (impossible?) to make a
type
| > safe Switch function...
|
| I use neither because the tend to become lengthy and spaghetti-like. I
| always use Select Case. But this is my personal preference, I guess.
|
| urs
 
Jay,
Odd, Select Case seems to be longer & more "spaghetti-like" then Choose,
especially for the simple cases where I would use choose Choose over Select
Case!

yes, the code is longer, but not "spaghetti-like" because it is clearly
structured. Also, I get intellisense for example when selecting with an
eNum. And it is far more flexible, because you can do things like "Case
0 to 2". And if you have more than 3 or 4 items to choose from, you end
up counting with your fingers to tell which one will be choosed with a
certain index.

So instead of replacing Choose with Select Case sometimes later, I use
Select case in the first place. By using a keyboard shortcut, I don't
even have to type much...

Best regards,
Urs
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top