Normally you can use any type to replace the generic type.
You can add constraints to a type parameter to require more specific type arguments.
These are the possible constraints:
Syntax | Meaning |
---|---|
where T : base-class | Base-class constraint |
where T : interface | Interface constraint |
where T : class | Reference-type constraint |
where T : struct | Value-type constraint (excludes Nullable types) |
where T : new() | Parameterless constructor constraint |
where U : T | Naked type constraint |
In the following code, GenericClass<T,U> requires T to derive from SomeClass (or itself) and implement Interface1, and requires U to provide a parameterless constructor:
class SomeClass { } interface Interface1 { } class GenericClass<T,U> where T : SomeClass, Interface1 where U : new(){ }
Constraints can be applied in both methods and type definitions.
A base-class constraint sets that the type parameter must subclass or match a particular class.
An interface constraint sets that the type parameter must implement that interface.
The following code creates a generic Max method to return the maximum of two values.
We can use the generic interface from C# called IComparable<T>:
interface IComparable<T>{
int CompareTo (T other);
...
}
Using this interface as a constraint, we can write a Max method as follows:
static T Max <T> (T a, T b) where T : IComparable<T> { return a.CompareTo (b) > 0 ? a : b; }
Max method can accept arguments of any type implementing IComparable<T>.
int z = Max (5, 10); // 10 string last = Max ("ant", "zoo"); // zoo
class constraint and struct constraint set that T must be a reference type.
The parameterless constructor constraint requires T to have a public parameterless constructor.
Then you can call new() on T:
static void Initialize<T> (T[] array) where T : new() { for (int i = 0; i < array.Length; i++) array[i] = new T(); }
The naked type constraint requires one type parameter to derive from or match another type parameter.
FilteredTable returns another Table, containing only the subset of elements where the type parameter U is of the type parameter T:
class Table<T> { Table<U> FilteredTable<U>() where U : T {...} }