Understanding Function Declaration

IanRyder

Well-known member
Joined
Sep 9, 2012
Messages
1,130
Location
Healing, NE Lincs, UK
Programming Experience
10+
Hi All,

I saw a Function declaration on the forum this morning which I am not familiar with and am hoping for some guidance on its usage.

This is what was posted on the forum:-
VB.NET:
Private Function FunctionName(Of T)(list As IEnumerable(Of T), count As Integer) As T()
  'do work
End Function

Even though this declaration is unfamiliar to me I was easily able to convert this declaration into something which I could easily understand. Being:-
VB.NET:
Private Function FunctionName(list() As Integer, count As Integer) As Integer()
  'do work
End Function

As to my questions:-

1) Am I right in thinking that the (Of T) in the first declaration is defining a generic list of objects that can be returned to the calling routine?

2) With Option Strict On, how is it that Visual Studio does not throw up it's usual type conversion issues when (Of T) is not defined as a specific type? I guess I am missing something about (Of T)?

3) Finally, are there any advantages in defining a Function declaration as shown in the first example as apposed to what is show in the second example or is this just a case of preference?

Thanks for any help you can provide.

Cheers,

Ian
 
Last edited:
1. No, you're not. Generics don't relate just to collections. You can have generic types and generic methods. List(Of T) is a generic class. It defines a collection of items where each item is of type T or a type that inherits or implements type T, where the type T is defined at run time. At run time, you can create a List(Of Integer), List(Of String), List(Of SomeOtherType) or whatever. The List(Of T) class has an Item property that is type T. By fixing the type T at run time as Integer, String, SomeOtherType or whatever, you also fix the type of the Item property to be Integer, String, SomeOtherType or whatever. That's how generics work: by fixing the type T in one place, you fix it everywhere.

That function is generic, which is what the (Of T) means. The first parameter of that function is type IEnumerable(Of T) and the return type is T(), i.e. a T array. As I said, with generics, when you fix T is one place you fix it everywhere. If you call that method and pass an IEnumerable(Of Integer) to the first parameter then the return type will be Integer(), i.e. an Integer array. If you pass an IEnumerable(Of String) then it will return a String(), if you pass an IEnumerable(Of SomeOtherType) then it returns a SomeOtherType(), etc.

With a generic method, sometimes you have to specify the generic type yourself because it cannot be inferred. Usually it can be inferred from the arguments though, so you don't have to specify it. For instance, you could call that method like this:
VB.NET:
Dim myIntegerArray As Integer() = FunctionName(Of Integer)(myIntegerList, count)
That way you are explicitly fixing the generic type as Integer. There's no need to fix T explicitly though because it can be inferred. The first argument is an IEnumerable(Of Integer) so T can be inferred to be type Integer. That means that the method can be called like this:
VB.NET:
Dim myIntegerArray As Integer() = FunctionName(myIntegerList, count)
2. By adding the (Of T) to the declaration of a type of method you are defining that type of function to be generic and you can then use T as a type anywhere in the definition of that type or method.

3. Your second declaration will only accept an Integer array as a parameter and will return an Integer array. The whole point of a generic type or method is that it will work for a whole range of types. The first declaration will accept an array of any type as an argument and return an array of the same type. Not only that, that first parameter will accept arrays, generic Lists, LINQ query results and anything else that implements the IEnumerable(Of T) interface.

Was that my method intended to select lottery numbers? If so then, in that specific case, the method could have been written in a more specific manner and still work but there are many situations where the generic declaration is best because it allows you to use the same method in many different scenarios. For instance, the ConvertAll extension method of an array can be called on any type of array and return any other type of array based on the return type of the delegate you pass as the converter.
 
Hi jcmilhinney,

Many thanks for your post. I have been looking at examples of this all morning and had sort of gotten to the right conclusions but your comments have clarified things perfectly. Thanks once again.

Cheers,

Ian
 
Back
Top