CSharp - Generics Generic Types

What are Generics?

Generics express reusability with a template and placeholder types.

Generics can increase type safety and reduce casting and boxing.

Example

A generic type declares type parameters(placeholder).

When using the generic type the placeholder will be filled in by the consumer of the generic type.

The following code defines a generic type Stack<T>.

Stack<T> declares a single type parameter T:

class Stack<T>
{
       int position;
       T[] data = new T[100];
       public void Push (T obj)  => data[position++] = obj;
       public T Pop()            => data[--position];
}

We can use Stack<T> as follows:

var stack = new Stack<int>();
stack.Push (5);
stack.Push (10);
int x = stack.Pop();        // x is 10
int y = stack.Pop();        // y is 5

Stack<int> replaces the type parameter T with the type int. 

Attempting to push a string onto Stack<int> would produce a compile-time error.

Stack<T> is an open type, whereas Stack<int> is a closed type.

At runtime, all generic type instances are closed by using the placeholder types.

This means that the following statement is illegal:

var stack = new Stack<T>();