Link Round-Up for 10/05/07Site News for 9/30/07 through 10/06/07

Rolling Your Own Generic Functions

October 5th, 2007

Rolling Your Own Generic FunctionsYou probably know that Generics, introduced to VB.NET in the .NET Framework 2.0, provide type safe Lists, Dictionaries, Stacks, Queues and other objects. But, did you know that you can use the same technique to build your own type safe functions? In this article, we’ll look at some of the basics of doing this.

Why Generics?

First, let’s look at why generics are important.

Prior to generics we had to base any general purpose routines either around a particular type or use System.Object. This meant that we couldn’t make a routine as general purpose as we might want or we had to use performance impacting boxing to place a value type, such as an integer, into a reference type. Plus we had to use type conversions in many places or, worse, not use Option Strict so that we could do implicit conversions.

With generics, we can work with any type but without incurring performance penalties associated with boxing/unboxing variables or doing any casting. More importantly, we’re insuring type safety and thus avoiding troublesome runtime errors. Using them also makes it easier to build single functions that can work with several different data types.

MyFunction(Of T)(…

To begin with, let’s look at how we can define generic type parameters in our own functions. Here’s a simple example that accepts a paramarray of values of a specified type and places then into a generic List of the specified type:

Private Function BuildList(Of T)(ByVal ParamArray values() As T) As List(Of T)
    Dim NewList As New List(Of T)
    NewList.AddRange(values)
    Return NewList
End Function

Notice that when the function is defined we specify a generic type first, (Of T), and then our parameters, followed by our return value. Here are some examples of calling this function:

'
'
Dim StringList As List(Of String) = BuildList(Of String)("test1", "Hello!", "Bye!")
'
'
Dim IntList As List(Of Integer) = BuildList(Of Integer)(1, 87, 48, 28, 24)
'
'

As you can see we’re calling the same function but using different data types.

You can also specify multiple types and you’re not limited to just using ‘T’ as the name, as we see in this example that merges two lists of the same size into a dictionary object:

Private Function MergeLists(Of TKey, TValue)(ByVal Keys As List(Of TKey), ByVal Values As List(Of TValue)) As Dictionary(Of TKey, TValue)
    Dim MergedDictionary As New Dictionary(Of TKey, TValue)
    If Keys.Count = Values.Count Then
        Dim Counter As Integer
        For Each Item As TValue In Values
            MergedDictionary.Add(Keys.Item(Counter), Item)
            Counter += 1
        Next
    End If
    Return MergedDictionary
End Function

Calling this function would look like these examples:

'
Dim MyItems As Dictionary(Of Integer, String) = MergeLists(Of Integer, String)(IntList, StringList)
'
'
Dim MyInventoryResults As Dictionary(Of Integer, InventoryItem) _
    = MergeLists(Of Integer, InventoryItem)(KeyList, MyInventoryItems)
'
'

Also, we can have specific types in our paramaters while returning a generic type. For example, this function accepts a DataTable and Integer and returns a List object of the specified type with data from the specified column index.

Public Function ColumnToList(Of T)(ByVal MyTable As DataTable, ByVal columnIndex As Integer) As List(Of T)
    Dim ReturnList As New List(Of T)
    For Each RowValue As DataRow In MyTable.Rows
        ReturnList.Add(DirectCast(RowValue(columnIndex), T))
    Next
    Return ReturnList
End Function

Any time when you’re coding and you think, “Well, I’ll have to have a separate routine for this data type, and this one, and this one, and this one too”, take the time to consider if using generics will work for you in that case. Often you’ll find that it will.

As always, if you have any questions or ideas on this topic, feel free to leave me a comment.

Share This Article: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • DotNetKicks
  • DZone

Entry Filed under: VB.NET Tutorials


Rate This Article:

Not That GoodCould Be BetterOKGoodGreat (7 votes, average: 4.57 out of 5)
Loading ... Loading ...

8 Comments Add your own

  • 1. BigJim  |  February 14th, 2008 at 2:54 pm

    This is as clear and thorough of an explanation as I have ever seen. I’ve been using generics for a while, in the manner that you mention (Lists, etc.) but never as a function. Quite an eye opener, and the power of this is super appealing! Your article totally covers everything about this feature, thanks much!

  • 2. Pat  |  May 14th, 2008 at 9:09 pm

    Thanks mate, wasn’t quite sure of the power of these generic functions, and, like the above poster, found it to be one of the best explanations I’ve ever seen on the power and versatility of the generic functions!
    Cheers!

  • 3. Chris  |  May 16th, 2008 at 2:29 pm

    This is a good article and I wished I had stumbled upon this a lot sooner as this would have saved me some VB.NET syntax headaches.

    I figured out how to create generic functions and have been using them in my applications now.

    Nevertheless, I will still hold on to this article.

  • 4. M.V.S Venu Madhav  |  May 22nd, 2008 at 3:10 am

    article is good and easy to understand.i would like to know about class templates in VB.net

  • 5. indra  |  October 20th, 2008 at 11:17 pm

    thanks for posting such a good article about generics

  • 6. Prasanthi  |  February 21st, 2009 at 11:44 am

    Very Informative for a beginner. thank you

  • 7. Vishal  |  May 15th, 2009 at 4:59 am

    Great Article! however I am still struggling to implement it for below scenario:
    I have function that returns an object to any of the defined custom classes. How can i make use of Generics in this case?

    Public Function getEntityData(ByVal EntityName As String, ByVal EntityKeyValue As String) As Object

    I declared a Function as:
    Public Function testgetSTEntityData(Of AnyVOType As {New}) (ByVal EntityName As String, ByVal EntityKeyValue As String) As AnyVOType

    Am wanting to return an object of any Custom classe’s that I have declared but am not able to do so and am getting design time error: Value of Type “some custom class” cannot be converted to AnyVOType.

    Can generics be used in this scenario ?

  • 8. Patrick  |  July 2nd, 2009 at 4:35 pm

    Great VB-centric explanation! Thank you.

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Visit Me At My New Site, Programming In C#

Most Popular Articles

Highest Rated Articles

Categories

Most Recent Articles

Feeds

 Subscribe in a reader

To subscribe by e-mail
Enter your address here

Delivered by FeedBurner

VB Opportunities

Archives