Logo: C# Computing
 
Web CsharpComputing.com

Generics Programming with C# 2.0

Generics is a mechanism to support multiple ("generic") types. For example, you are creating a Stack data structure. What
kinds of objects would you want to store on the stack: Integers, strings, Cars? In C# 1.x you have to use an untyped container that stores object items and requires conversions between the type you store and object every time an item is inserted or removed from the Stack. There are two disadvantages to storing items as objects (VARIANTS in Visual Basic). Firstly, casting between object and and the type is computationally expensive. (See http://CshaprComputing.com/Tutorials/Lesson23.htm for benchmarks).

Secondly, the resulting container is untyped which results in even slower code due to  run time exceptions  C# 2.0. (Whidbey) introduces generics that support creation of typed data structures.

Example below (this is an extension of MSDN example ms-help://MS.VSCC.v80/MS.MSDNQTR.v80.en/MS.MSDN.v80/MS.VisualStudio.v80.en/dv_csref/html/a1ad761e-42f7-41dd-a62f-452a2de26b9d.htm) illustrates how to build a linked list with Generics. MyList object contains a list of elements of type T and supports inserting, extracting and removing elements from the list, as well as, enumeration of list elements. If you have experience with C++ templates abhor the difficulties of template debugging C++ template code difficult, do not fret C# generics. Type resolutions in C# generics is at compile time, so when you run this program through the debugger, MyList will appear as an List that accepts only integers.

public class MyList<T> {
    private Node head;
    private class Node
    {
        private Node next;
        private T data;
        public Node(T t)
        {
            next =
null;
            data = t;
        }
        public Node Next
        {
            get { return next; }
            set { next = value; }
        }
        public T Data
        {
            get { return data; }
            set { data = value; }
           }
        }
        public MyList()
        {
            head =
null;
        }
        public void AddHead(T t)
        {
            Node n = new Node(t);
            n.Next = head;
            head = n;
        }
        public T GetItem(int index)
        {
            Node current = head;
            int counter = 0;
            while (current != null && counter < index)
            {
                counter++;
                current = current.Next;
            }
            return current.Data;//may generate out of range or null exception
           
          }
        public void RemoveItem(int index)
        {
            Node current = head;
            int counter = 0;
            if (index == 0)
            {
                //To DO
                return;
            }
            while (current != null && counter < (index-1))
            {
                counter++;
                current = current.Next;
            }
            if (counter != (index-1) || current == null)
                throw new IndexOutOfRangeException();
            Node newNext = current.Next.Next;//handle possible null here
            current.Next = newNext;
          }
        public void InsertItem(int index, T data)
        {
            Node current = head;
            Node newNode = new Node(data);
            int counter = 0;
            if (index == 0)
            {
            //To DO
                return;
             }
            while (current != null && counter < index)
            {
                counter++;
                current = current.Next;
            }
            newNode.Next = current.Next;
            current.Next = newNode;
         }
        public IEnumerator<T> GetEnumerator()
        {
            Node current = head;
            while (current != null)
            {
                yield return current.Data;
                current = current.Next;
            }
        }
   }
class Test
{
 
static void Main(string[] args)
    {

    MyList<int> list = new MyList<int>();
    for (int x = 0; x < 10; x++)
        list.AddHead(x);
        // list.RemoveItem(3);
        list.InsertItem(3, 22);
        foreach (int i in list)
        {
            Console.WriteLine(i);
        }
        // Console.WriteLine(list.GetItem(3));
        Console.WriteLine("Done");
      }
    }
}