Understanding C# Generics


 

Introduction

Before we starttampering around the code, lets understand why we need a generic type? Well inmost of application development we come across lots of situation where we need atype which can hold both value types and reference type. In this situation weneed a generic type which can do both. Before we start working on generic type,lets understand little about types in .Net as we know there are two fundamentalcategories of types

 1]valuetypes     (example : structures,primitive type,enums)

 2]referencetypes (example : Classes,interface,arrays,strings etc..,)

So when you areusing any one of the above types they are bonded to that particular type. Forexample if we declare a structure it bonds to value type and when we declare aclass it bonds to reference type. Despite the fact that declaration syntax issame for both but semantics are distinct.  Andin terms of memory allocation for value is on stack and where as for referencetype is on run-time heap.

Assignment to a variable of value types createsa copy of the value.

For example:  

//vtyp.cs<o:p></o:p>

using System;
public class valTyp
{
public static void Main()
{
Int32 I=10,J=0;
J=I; 
// this will create a copy value I into J 
I++;
Console.WriteLine( "I value: {0}, J value {1}",I,J);
}
}

Output:

D:\vstudio>vtype
I value: 11, J value 10

The assignment tothe local variable J does not impact the local variable I becauseboth local variables are of a value type (the type Integer) and eachlocal variable of a value type has its own storage.

But Assignment to avariable of a reference type creates a copy of the reference, not a copy of thevalue being referenced let?s see this with an example below.

For example:  

//vref.cs
<o:p></o:p>using System;
public class Cclass
{
public int val = 0;
}
public class refTyp
{
public static void Main()
{
Cclass ref1 = new Cclass();
Cclass ref2=ref1;
ref2.val = 555;
Console.WriteLine( "Before increament Ref1 value: {0}, Ref2 value {1}",ref1.val,ref2.val);
ref2.val++;
Console.WriteLine( "After increament Ref1 value: {0}, Ref2 value {1}",ref1.val,ref2.val);
 }
}
Output:

D:\vstudio>vref
Before increament Ref1 value: 555, Ref2 value 555
After increament Ref1 value: 556, Ref2 value 556

In contrast withvalue type the assignment to reference type variable ref2.val = 555,affects the object that both ref1 and ref2 reference.

From above we seethat value types and reference types are different. So to create a Generictype we need something which neither of them. In .net we have theroot type Object (alias System.Object)is special in that it is neither a reference type nor a value type, and may notbe instantiated. So a variable of type Objectcan either contain a value type or a reference type. Yes there is question,which arises in mind why Object class canhandle both?

The answer is bothreference and value types are derived from the base class Object.So using the concept Boxing and unboxing we can treat any typeas an object. So what does boxing do, So where its necessary for a value type tobehave like a object boxing is done which wrappers the value type to look like areference object (allocated on heap), and the value type?s value is copiedinto it. Then this complete wrapper is marked so that CLR knows that itcontains a value type. Similarly the reverse process is called as unboxing.

Let?s see a sample code using Objectclass as Generic type:

// objapp.cs<o:p></o:p>

usingSystem;

publicclass Myclass

{

  >public stringname="Hello from Myclass";

 public voiddoSomething()

 {

  Console.WriteLine(name);

 }

}

publicclass ObjApp{

 publicstatic void CheckType(object o)

  {

     if(o is string)

      {

        Console.WriteLine ("o isString");

        string s = (string)o;

        Console.WriteLine (s);

      }

     

      elseif (o is Int32[])

      {

        Console.WriteLine ("o is Int32array");

        Int32[] ins=(Int32[])o;

        for(Int32 i=0;i< ins.Length;i++)

        Console.WriteLine (ins[i]);

      }

      elseif (o is Myclass)

      {

        Console.WriteLine ("o isMyclass");

          Myclass a = (Myclass)o;

          a.doSomething();

        }

  }

  public staticvoid Main(){

      //Create an array of Object references

      Object[]objs = new Object[3];   

      objs[0]= "Some String";        // create a new string

      objs[1]= new Int32[]{1, 2, 4}; // create a new Int32 array

      objs[2]= new Myclass();         // create a newObject instance

      for(Int32ind = 0; ind < 3; ind++)

        {

        Console.WriteLine("Array index{0} refers to {1}",ind, objs[ind]);

        ObjApp.CheckType(objs[ind]);             

         }

 <o:p></o:p>

  }

}

 <o:p></o:p>

Output:

Arrayindex 0 refers to Some String

o isString

SomeString

Arrayindex 1 refers to System.Int32[]

o isInt32 array

1

2

4

Arrayindex 2 refers to Myclass

o isMyclass

Hellofrom Myclass

 <o:p></o:p>

 <o:p></o:p>

Inthe above program if you see Object classcan take any type and in CheckType memberfunction we are sending the generic type (Object)and using is operator we are checking thetype which is passed as parameter to the function , Then using Boxingwe can point to the specific type and use for further processing.

 <o:p></o:p>

 <o:p></o:p>

Furtherreading <o:p></o:p>

  1. .Net  More information on .Net technologies

 Aboutthe Author: ChandraHundigam has Master degree is Computer Application, Working on MicrosoftTechnologies for past 5 years. Presently working as consultant for a US basedcompany. His area of interests is Emerging Technologies.

Twitter Digg Delicious Stumbleupon Technorati Facebook Email

No comments yet... Be the first to leave a reply!