Explanation:
Generics are considered an advanced and powerful idiom in any language. When I first encountered templates in C++, they seemed a little confusing. Then I read Bjarne Stroustrop's The Design and Evolution of C++, and templates seemed as easy to use as the C macros and simple string-replacement templates they supplanted. Templates and generics are the same thing—though their implementations are slightly different.
Generics in C# support defining algorithms and deferring the data type until the point of use. In early versions of C#, we arguably could live without generics because every type was derived from a common base type: object. This meant that programmers could define a Stack class based on the object type and put anything in the Stack (because everything's earliest ancestry is an object). However, a Stack of objects meant that Customer objects, Integer objects, and Foo objects could all be placed in the same Stack instance. The result was that developers subclassed data types to tighten up the type of data with which they interacted. For example, when writing custom business objects, it was a recommended practice to define strongly typed collections derived from System.Collections.CollectionBase. The reason is simple: Defining everything based on objects is considered weak typing.
Generics in C# support some additional refinements. For example, a method or class can have more than one parameterized type, and generics in C# support WHERE constraints that refine the type of the parameterized types. For example, if a generic type must implement IDisposable, C# generics support expressing this limitation.
If you explore System.Collections.Generic namespace there are several generic data structures that support typed collections, hashes, queues, stacks, dictionaries, and linked lists. To use these powerful data structures, all you have to do is provide the data type.
Here we look at very simple example of using Generic Collection;
using System;
using System.Collections.Generic;
using System.Text;
namespace Generics
{
class Program
{
static void Main(string[] args)
{
List customers = new List();
customers.Add(new Customer("Motown-Jobs"));
customers.Add(new Customer("Fatman's"));
foreach (Customer c in customers)
Console.WriteLine(c.CustomerName);
Console.ReadLine();
}
}
public class Customer
{
private string customerName = "";
public string CustomerName
{
get { return customerName; }
set { customerName = value; }
}
public Customer(string customerName)
{
this.customerName = customerName;
}
}
}
Here we have a strongly typed collection—List—without writing a single line of code for the collection class itself. If we wanted to extend the customer list, we could derive a new class by inheriting from List.
Implementing Genaric Classes;
Now, we can define our own Generic class and later we will implement it by simple example:
// type parameter T in angle brackets
public class GenericList
{
// The nested class is also generic on T
private class Node
{
// T used in non-generic constructor
public Node(T t)
{
next = null;
data = t;
}
private Node next;
public Node Next
{
get { return next; }
set { next = value; }
}
// T as private member data type
private T data;
// T as return type of property
public T Data
{
get { return data; }
set { data = value; }
}
}
private Node head;
// constructor
public GenericList()
{
head = null;
}
// T as method parameter type:
public void AddHead(T t)
{
Node n = new Node(t);
n.Next = head;
head = n;
}
public IEnumerator GetEnumerator()
{
Node current = head;
while (current != null)
{
yield return current.Data;
current = current.Next;
}
}
}
The following code example shows how client code uses the generic GenericList class to create a list of integers. Simply by changing the type argument, the code below could easily be modified to create lists of strings or any other custom type:
class TestGenericList
{
static void Main()
{
// int is the type argument
GenericList<int> list = new GenericList<int>();
for (int x = 0; x < 10; x++)
{
list.AddHead(x);
}
foreach (int i in list)
{
System.Console.Write(i + " ");
}
System.Console.WriteLine("\nDone");
}
}
|