Tuesday, 30 January 2007

Constraints On Type Parameters

When defining a generic class, you are able to apply restrictions to the kinds of type that client code can use type arguments when it instatiates your class. If a client attempts to instantiate your class with a type that is not allowed by a constant, the result will be a compile-time error. There are six types of constraint available.

where T : struct
The type argument must be a value type. Any value type except Nullable can be specified.

where T : class
The type argument must be a reference type, including any class, interface, delegate, or array type.

where T : new()
The type argument must have a public parameterless constructor. When used in conjunction with other constraints, the new() constraint must be specified last.

where T : <base>
The type argument must be or derieve from the specified base class.

where T : <interface>
The type argument must be or implemented the specified interface. Multiple interface constraints can be specified. The constraining interface can also be generic.

where T : U
The type argument supplied for T must be or derieve from the argument supplied for U. This is called a naked type constraint.


class EmployeeList<T>
where T : Employee, IEmployee, System.IComparable
<T>, new
()
{
// ...

}
Applying constrains allows you to use methods on base types as you count on the type passed in supporting the method.  Within this generic code we are able to call methods specified by IEmployee because the generic type must implement IEmployee, removing this constraint and calling a method within IEmployee directly in the Generics code would lead to a compile time error. 

2 comments:

Unknown said...

In your example, where T : Employee, is Employee an example of a naked type constraint?

Developer Dave said...

Not in this case, a naked type constraint would be

public class Employee&alt;T, U, V&glt; where T : V {}

Confusing I know, but the its use is very limited because the .NET compiler can assume nothing about a naked type constraint except that it derives from System.Object. You use naked type constraints on generic classes in scenarios in which you wish to enforce an inheritance relationship between two type parameters.

The example I used was the simple

where T: class (The type argument must be a reference type).