Friday, February 17, 2012

Generics in .NET Framework

If you came from C++ and worked on a VB 6.0 application, one thing that stood out like a sore thumb was the lack of templates. Templates in C++ allowed for type-safety and code re-usability. In VB 6.0 and in earlier versions of .NET Framework (1.0 and 1.1), you did something like this

Public Sub Add(ByVal param1 As Object, ByVal param2 As Object)

      If TypeOf(param1) = GetType(String) AND TypeOf(param2) = GetType(string) Then

              console.writeline("String=" & param1.ToString & param2.ToString)

      Else If TypeOf(param1) = GetType(int) AND TypeOf(param2) = GetType(int) Then

             console.writeline("Integer=" & DirectCast(param1,int) + DirectCast(param2,int)

      End If

End Sub

Note - C# also suffered from same limitation in 1.0 and 1.1

Aside from all the typecasting, there is something else going on here. Recall from my previous post about boxing and unboxing. If you passed integer values to this method, the passed values will be boxed and then DirectCast will unbox these values since integer is a value type.

Although this provided you flexibility in the sense that you didn't have to write two separate methods - one for numeric operation and one for string operation, it came at a performance cost.

Even if you avoided methods like these, using an arraylist with value types will result in boxing/unboxing as well (recall an example in previous post).

.NET 2.0 introduced the concept of generics. Generics allow you to define a type-safe method, class or structure without committing to a specific data type. You can write code that is just as flexible as the above example, promotes code re-use without the performance degradation of boxing / unboxing.

 Lets consider an example. Assume you want to use the flexibility of an arraylist but without its drawbacks, you can create a generic list object that framework will convert to a passed data-type during compile time.


List<int> Test = new List<int>();     //a list of type int
Test.Add(1);     //no boxing
Test.Add(2);
Test.Add("A");    //compile time error - type safe


Generic Method



void Add<T>(ref T param1)
       {
           T results;
           results = param1;
           Console.WriteLine(results);
       }


You can also declare a generic class or a structure.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace GenericTest
{
    class GenericList<T>
    {
        void AddToList(T input) { }
    }
}



//Test Generic Class

GenericList<int> list1 = new GenericList<int>(); // list of type int
GenericList<string> list2 = new GenericList<string>(); // list of type string


As I previously mentioned, Generics allow for code re-use without compromising performance. Generics was perhaps one of the most powerful enhancement in .NET Framework 2.0.

As always, your comments are welcome.



No comments:

Post a Comment