CSharp examples for Custom Type:Generics
By default, a type parameter can be substituted with any type.
Constraints can be applied to a type parameter to require more specific type arguments.
These are the possible constraints:
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 example, GenericClass<T,U> requires T to derive from (or match) SomeClass 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 wherever type parameters are defined, in both methods and type definitions.
A base-class constraint specifies that the type parameter must subclass (or match) a particular class;
An interface constraint specifies that the type parameter must implement that interface.
These constraints allow instances of the type parameter to be implicitly converted to that class or interface.
For example, suppose we want to write a generic Max method, which returns the maximum of two values.
We can take advantage of the generic interface defined in the framework called IComparable<T>:
public interface IComparable<T> // Simplified version of interface { int CompareTo (T other); }
CompareTo returns a positive number if this is greater than 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; }
The Max method can accept arguments of any type implementing IComparable<T> (which includes most built-in types such as int and string):
int z = Max (5, 10); // 10 string last = Max ("ant", "zoo"); // zoo