Solution Builder - Channel Insider
Empowering the next generation Channel
 

Bull’s Eye Awards
Nominations Open for Channel Insider 2009 Bull’s Eye Awards
Nominations are now open for the Channel Insider 2009 Bull’s Eye Awards, which recognize excellence in customer service, technology prowess, business acumen, channel leadership, communications and community building, and innovation among vendors, solution providers, distributors and channel services companies.



Sponsored Links
  • Control VM Sprawl, What You Don’t Know Can Hurt You
  • FREE Sophos Encryption Tool: Encrypt, compress and share files easily
  • LSI 6Gb/s Portfolio Expands to Include SATA+SAS HBAs
  • Reduce the cost of managing your mobile workers.
  • Find out 7 Ways to Drive Data Center Efficiency
  • SonicWALL breaks through network and email gridlock
  • Save up to 40% on calling costs with Avaya Aura™



  •  

    Generic Methods in Visual Studio 2005

    in Solution Builder


    Article Rating:starstarstarstarstar / 1
    Article Views: 2925

    Rate This Article:
    Add This Article To:
    You might think generics and templates are very hard to use, but they aren't, not really. Paul Kimmel shows you how to define generic methods and explains their implementation in .NET 2.0, using C# and VB examples. And he makes it simple. Honest.

    Some things are good in their own time. Bell bottoms were deemed to be good in the 1970s, but today, after a short revival, they are considered goofy. In contrast, blue jeans have always been deemed to be good, whether you choose Wranglers or Levi's. The same thing is true of code idioms: some idioms are always good, and some are good in their own time.

    For example, templates are deemed good, but for VB.NET programmers their time hadn't come until now. Called generics in .NET, Microsoft is introducing generics into languages like C# and VB.NET. (Microsoft could have introduced generics into VB earlier, but the audience probably just wasn't ready.)

    Unlike bell-bottoms, generics have always been useful, because they help eliminate the need to write the same algorithm over and over when the only thing that changes is data type — think Stack algorithm — and they help eliminate ugly conditional type checking and coercion. Now, C# and VB.NET support generics.

    Historically, generics and templates have been perceived as very hard to use, but they aren't, not really. In this article, I demonstrate how to define generic methods and tell you about their implementation in .NET 2.0.

    The Problems Generics Solve

    .NET has a common type system. This means all objects have, at their absolute root, a class named object, even simple types like int/Integer. In a technical sense, this means that you could write an abstract data type, Stack (although one already exists), and store objects in it. Since Stack already exists, Listing 1 offers a simple example that illustrates a problem with stacks based on a common subtype.

    Listing 1: Problems with common sub-types and data structures.

    Imports System.Collections
    
    Module Module1
    
        Sub Main()
          Dim s As Stack = New Stack
          s.Push(New Gun)
          s.Push(New Camera)
          
          While (s.Count > 0)
            Dim o As Object = s.Pop
            o.Aim()
            o.Shoot()
          End While
    
          Console.ReadLine()
    
        End Sub
    
    End Module
    
    Public Class Gun
      Public Sub Aim()
    
      End Sub
    
      Public Sub Shoot()
        Console.WriteLine("You're dead")
      End Sub
    End Class
    
    Public Class Camera
      Public Sub Aim()
    
      End Sub
    
      Public Sub Shoot()
        Console.WriteLine("You're a supermodel")
      End Sub
    End Class

    From the example in Listing 1, you see that we can put any type of object in the basic Stack class. The result is that, without a lot of type checking and type coercion, we can't be sure that some unexpected type hasn't found its way in the stack, resulting in an unanticipated runtime error, or worse, supermodels with holes in them.

    Resource Library:

    One solution is to write a type-specific Stack for each kind of object we want to store using a stack. Generics eliminate the need to write type-specific stacks (or anything else), and eliminate the need to for type checking and type coercion. Well, slightly more precisely, Generics eliminate the need to us to write type-specific algorithms, which in turn also eliminates the need to write type-checking and type-coercing code.

    Using a Generic Stack

    The problem is easily mitigated by using generics. In our supermodel-homicide example, we can use the System.Collections.Generic.Stack class, which would prevent us from shooting the supermodel with the Gun, because Gun wouldn't be permitted in a stack of cameras (see Listing 2).

    Listing 2: A revision of listing 1 that uses a Generic stack ensuring type homogeneity. Imports System.Collections.Generic.

    Module Module1
    
        Sub Main()
          'Dim s As Stack = New Stack
          Dim s As Stack(Of Camera) = New Stack(Of Camera)
          's.Push(New Gun)
          s.Push(New Camera)
          
          While (s.Count > 0)
            Dim o As Object = s.Pop
            o.Aim()
            o.Shoot()
          End While
    
          Console.ReadLine()
    
        End Sub
    
    End Module
    
    Public Class Gun
      Public Sub Aim()
    
      End Sub
    
      Public Sub Shoot()
        Console.WriteLine("You're dead")
      End Sub
    End Class
    
    Public Class Camera
      Public Sub Aim()
    
      End Sub
    
      Public Sub Shoot()
        Console.WriteLine("You're a supermodel")
      End Sub
    End Class

    In the revised example, trying to put Gun in the Stack(Of Camera) would report a compile-time error, which effectively means we wouldn't be shooting supermodels with guns, even by accident.

    Generic methods can be written independently, or as part of a generic class. They are the first step toward creating type agnostic solutions. In the rest of this article, we focus on writing generic methods.

    Writing a generic class is easy once you know how to write generic methods. Simply wrap the generic method in a class, and add the notation to the class header for the permits specifying the generic type when the class is declared and instantiated.

    Defining Generic Methods

    A generic method is a method where one or more parameter types are unspecified in the method header. It is up to the method caller to provide the data type at each point of invocation. In C# and in VB.NET, this means we use a non-data type for at least one parameter type; T is used by convention. It also means that we use an extended notation specific to the language. In C#, we add a <T> after the method name before the parentheses, and in VB.NET we use an (Of T) after the method name and before the parameter parentheses. (Listing 3 provides a VB.NET example; Listing 4 is a C# example.)

    It is worth noting that we can have multiple generic types. Return types and local parameters can be defined as the generic type, too.

    Listing 3: A generic method body for Pop in VB.NET.

    Public Function Pop(Of T)() As T
    
    End Function
    
    Listing 4: A generic method body for Pop in C#.
    public T Pop<T>()
    {
    }

    The just-in-time compiler for .NET is responsible for converting a method call against these generic methods into a type-specific method instance based on the type provided at invocation. For example, to use the stand-alone C# Pop method to Pop a Camera instance, we would call Pop this way:

    Pop<Camera>

    Adding Generic Method Constraints

    Generic methods in .NET support optional method constraints that limit the kinds of data types with which a particular method can be invoked. In C#, this is accomplished by using a

    WHERE T : is_kind

    predicate at the end of the method header and an

    (Of T As is_kind)

    after the Of T predicate, when defining a generic constraint for VB.NET. For example, we could define a generic method named Swap ,and limit possible types to non-nullable structures like int/Integer but not string/String by using a generic constraint. Listing 5 shows Swap in VB.NET, and Listin6 shows Swap in C#. Both have the constraint that limits the generic method to struct/Structure.

    Listing 5: Demonstrates a generic method with a structure constraint in VB.NET.

    Module Module1
    
        Sub Main()
          Dim I As Integer = 5
          Dim J As Integer = 7
          Swap(Of Integer)(I, J)
          Console.WriteLine("I = " & I)
          Console.WriteLine("J = " & J)
          Console.ReadLine()
    
        End Sub
    
    
        Public Sub Swap(Of T As Structure)(ByRef a As T, ByRef b As T)
          Dim temp As T = a
          a = b
          b = temp
        End Sub
    
    End Module

    After Swap(Of Integer)(I, J) is called, I is 7 and J is 5.

    Listing 6: Swap implemented as a C# method with the struct constraint. This code produces results identical to the code in Listing 5.

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace SwapInCSharp
    {
      class Program
      {
        static void Main(string[] args)
        {
          int i = 5;
          int j = 7;
          Swap(ref i, ref j);
          Console.WriteLine("i = " + i.ToString());
          Console.WriteLine("j = " + j.ToString());
          Console.ReadLine();
        }
    
        public static void Swap(ref T a, ref T b) where T : struct
        {
          T temp = a;
          a = b;
          b = temp;
        }
      }
    }

    The complete list and definition of possible constraints is provided in the .NET help documentation. By definition, generic types can be limited to structures, classes, classes with default constructors, base classes, and specific interfaces.

    Tip: An example of a nullable struct/Structure is the string/String class. The int/Integer is not nullable can be coerced to be nullable by adding a question mark (?) after the data type. As defined in Listings 5 and 6, we couldn't use this version of Swap for string/String types.

    Writing Generic Class Headers

    To create generic classes, all you need to do is have a class with at least one generic member and a means of letting the class consumer specify the actual type of the generic member. This is done in the class header, much the same way it is accomplished in a generic method.

    To define a generic class in VB.NET, add the (Of T) predicate after the class name, and to define a generic class in C# add a <T> after the class name. When you create an instance of the class, simply specify the data type of the generic parameter T. That's all there is to it.

    Summary

    There are a lot of small subtleties in how generic methods are defined and used, but the basic use is simple: convert the data type of parameters and local variables to the named generic type reference, and you are all set. Figuring out when to use generic methods takes some practice; their implementation in .NET is comparatively easy.

    The good news is that you do not need generics every day. You should not let their presence intimidate you, because you don't have to use generics at all. Generics do provide useful benefits without presenting any practical limitation to getting started with Visual Studio 2005 today.

    Paul Kimmel is the founder of Software Conceptions, Inc, founded in 1990, and the co-founder of the Greater Lansing Area .NET Users Group. Look for his upcoming book, UML DeMystified.





    Discuss Generic Methods in Visual Studio 2005
     
    >>> Be the FIRST to comment on this article!
     

     
     
    >>> More Solution Builder Articles          >>> More By Paul Kimmel
     


     


    [ci] feeds
    XML
    Add Channel News, Product Reviews, Trends and Analysis to your RSS newsreader or My Yahoo!


    HTML PLAIN TEXT

    Keep on top of news for VARs and Resellers with CI's Weekly Newsletter and Alerts.

     


    CHANNEL RESOURCE CENTER
     
     
    Enterprise Mobility Zone
    The Enterprise Mobility Zone (EMZ) blog is a tool designed to help senior IT executives discuss, create and deploy next-generation mobile strategies in their organizations.
    Go beyond yesterday's tactical approach to mobility!
     
    Build A More Efficient Data Center
    Demands are growing but budgets are not. Solve your pressing IT issues using the resources you already have. Determine which technologies can help you drive efficiencies and how they are applied. Gain a quick ROI on new initiatives
    Find out how
    Let Enterprise TechBrief do the work for you. Aggregated content, tech news, product reviews, vendor updates, how-to’s—all you need to boost your efficiencies and cut costs, all from one place.
    enterprisetechbrief.com