Generics
C# has two separate mechanisms for writing code that is reusable across different types: inheritance and generics. Whereas inheritance expresses reusability with a base type, generics express reusability with a “template” that contains “placeholder” types. Generics, when compared to inheritance, can increase type safety and reduce casting and boxing.
Generic Types
A generic type declares generic
parameters—placeholder types to be filled in by the consumer of the generic
type, who will supply the generic arguments. Here is a generic type
Stack<T>
, designed to stack instances of type
T. Stack<T>
declares a single generic parameter
T:
public class Stack<T>
{ int position;T
[] data = newT
[100]; public void Push (T
obj) { data[position++] = obj; } publicT
Pop() { return data[--position]; } }
We can use Stack<T>
as follows:
Stack<int>
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>
fills in the generic parameter
T
with the generic argument int
, implicitly creating a type on the fly (the synthesis occurs at runtime).
Stack<int>
effectively has the following
definition (substitutions appear in bold, with the class name hashed out to avoid
confusion):
public class ### { int position;int
[] data; public void Push (int
obj) { data[position++] = obj; } publicint
Pop() { return data[--position];} }
Technically, we say that Stack<T>
is an
open type, whereas Stack<int>
is a closed type. You can only ...
Get C# 3.0 Pocket Reference, 2nd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.