Generics in C#
Generics introduced in C# 2.0. Generics allow you to define a class with placeholders for the type of its fields, methods, parameters, etc. Generics replace these placeholders with some specific type at compile time.
A generic class can be defined using angle brackets <>. For example, the following is a simple generic class with a generic member variable, generic method and property.
class MyGenericClass<T>
{
private T genericMemberVariable;
public MyGenericClass(T value)
{
genericMemberVariable = value;
}
public T genericMethod(T genericParameter)
{
Console.WriteLine("Parameter type: {0}, value: {1}", typeof(T).ToString(),genericParameter);
Console.WriteLine("Return type: {0}, value: {1}", typeof(T).ToString(), genericMemberVariable);
return genericMemberVariable;
}
public T genericProperty { get; set; }
}
As you can see in the above code, MyGenericClass is defined with <T>. <> indicates that MyGenericClass is generic and the underlying type would be defined later, for now consider it as T. You can take any character or word instead of T.
Now, the compiler assigns the type based on the type passed by the caller when instantiating a class. For example, the following code uses the int data type:
MyGenericClass<int> intGenericClass = new MyGenericClass<int>(10);
int val = intGenericClass.genericMethod(200);
Return type: int, value: 10
The following figure illustrates how the compiler will replace T with int in MyGenericClass.
The above MyGenericClass<int>
class would be compiled, as shown below.
class MyGenericClass
{
private int genericMemberVariable;
public MyGenericClass(int value)
{
genericMemberVariable = value;
}
public int genericMethod(int genericParameter)
{
Console.WriteLine("Parameter type: {0}, value: {1}", typeof(int).ToString(), genericParameter);
Console.WriteLine("Return type: {0}, value: {1}", typeof(int).ToString(), genericMemberVariable);
return genericMemberVariable;
}
public int genericProperty { get; set; }
}
You can use any type while instantiating a MyGenricClass. For example, the following example uses a string type.
MyGenericClass<string> strGenericClass = new MyGenericClass<string>("Hello Generic World");
strGenericClass.genericProperty = "This is a generic property example.";
string result = strGenericClass.genericMethod("Generic Parameter");
Return type: string, value: Hello Generic World
Generic Class as Base Class
When deriving from a generic base class, you must provide a type argument instead of the base-class's generic type parameter as shown below.
class MyDerivedClass : MyGenericClass<string>
{
//implementation
}
If you want the derived class to be generic then no need to specify type for the generic base class.
class MyDerivedClass<U> : MyGenericClass<U>
{
//implementation
}
If the generic base class has constraints, the derived class must use the same constraints.
class MyGenericClass<T> where T: class
{
// Implementation
}
class MyDerivedClass<U> : MyGenericClass<U> where U: class
{
//implementation
}
The followings can be generic in C#:
- Interface
- Abstract class
- Class
- Method
- Static method
- Property
- Event
- Delegates
- Operator
Advantages of Generics
- Increases the reusability of the code.
- Generic are type safe. You get compile time errors if you try to use a different type of data than the one specified in the definition.
- Generic has a performance advantage because it removes the possibilities of boxing and unboxing.
- Generics denotes with angel bracket <>.
- Compiler applys specified type for generics at compile time.
- Generics can be applied to interface, abstrct class, method, static method, property, event, delegate and operator.
- Generics performs faster by not doing boxing & unboxing.