Sunday, 9 September 2012

Generics and How to write Generic class.


A Generic Class is not specific to any particular DataType. But the instance of such a class would be specific to a given DataType mentioned at the time of creating the instance/object that class.

Generic classes and methods combine reusability, type safety and efficiency in a way that their non-generic counterparts cannot. Generic collection classes are like Templates in C++.

Advantages of Generics

·         Type Safety -- Generic types enforce type compliance at compile-time, and not run-time (as in the case of using Object). This reduces the chances of data-type conflict during run-time.

·         Performance -- The data types to be used in a Generic class are determined at compile-time, hence there is no need to perform type casting during run-time, which is a computationally costly process.

·         Code reuse -- Since you only need to write the class once and customize it to use with the various data types, there is a substantial amount of code-reuse.


Easiest approach to write Custom Generic class: Let’s do this with an example:

Step1: First write a class for a specific data type.

For example below you will find an Stack Class with int datatype – Stack of int.

public class Stack
{
    int[] data;
    int top = -1;
    public Stack(int size)
    {
        data = new int[size];
    }
    public void Push(int value)
    {
        top++;
        data[top] = value;
    }
    public int Pop()
    {
        int value = data[top];
        top--;
        return value;
    }
    public int GetTopElement()
    {
        return data[top];
    }
    public void Print()
    {
        for (int i = 0; i <= top; i++)
            Console.WriteLine(data[i]);
    }
}

Limitation: In type of class can be used only for one datatype and for every data type we want to


Step2: Replace the specific datatype (eg: int) with Object and ensure that it still doesn’t have any errors:
 
public class Stack
{
    object[] data;
    int top = -1;
    public Stack(int size)
    {
        data = new object[size];
    }
    public void Push(object value)
    {
        top++;
        data[top] = value;
    }
    public object Pop()
    {
        object value = data[top];
        top--;
        return value;
    }
    public object GetTopElement()
    {
        return data[top];
    }
    public void Print()
    {
        for (int i = 0; i <= top; i++)
            Console.WriteLine(data[i]);
    }
}
 
Limitation: Because Object datatype is used in same instance we can have "int" and "string"...this makes the above class as NOT TYPESAFE....

 
Step3: Replace object with T (Generic Type) as in example below:
 
public class Stack<T>
{
    T[] data;
    int top = -1;
    public Stack(int size)
    {
        data = new T[size];
    }
    public void Push(T value)
    {
        top++;
       data[top] = value;
    }
    public T Pop()
    {
        T value = data[top];
        top--;
        return value;
    }
    public T GetTopElement()
    {
        return data[top];
    }
    public void Print()
    {
        for (int i = 0; i <= top; i++)
            Console.WriteLine(data[i].ToString());
    }
}

This class can be used as in program below:
class Program
{
    static void Main(string[] args)
    {
        Stack<int> s = new Stack<int>(5);
        s.Push (2);
        s.Push (5);
        s.Push (22);
        s.Push(“Demo”); //Compilation Error.
        s.Print();
       Stack<string> ss = new
                                          Stack<string>(10);
        ss.Push ("Demo");
        ss.Push("Test");
    }
}

Conclusion:
This same stack class can be used for instantiating for “int” and “string”….
Same generic class can be reused for different datatypes for different objects and a particular instance would allow only one type of item. That is why we say that generic classes give us the advantage of reusability and type safety.

No comments:

Post a Comment