// Example code taken from examples on http://www.codeguru.com/csharp/sample_chapter/article.php/c11673/C-Generics-Part-24-Constraints-Members-Operators.htm
// If you wish to use certain members of the instances of a parameter type in a generic, you must apply a derivation constraint. Here is an example which illustrates the syntax:
//
//
// Example 7
interfaceICustomInterface7{intFct();}
classC7<U>whereU:ICustomInterface7{
publicintAnotherFct(Uu){returnu.Fct();}
}
// You can apply several interface implementation constraints and one base class inheritance constraint on a same type parameter. In this case, the base class must appear in the list of types. You can also use this constraint conjointly with the default constructor constraint. In this case, the default constructor constraint must appear last:
// You cannot use a sealed class or a one of the System.Object, System.Array, System.Delegate, System.Enum or System.ValueType class as the base class of a type parameter.
//
//
// You also cannot use the static members of T like this:
//
//
// Example 9
classBaseClass9{publicstaticvoidFct(){}}
classC9<T>whereT:BaseClass9{
voidF(){
/*commentedouttobuild
// Compilation Error: 'T' is a 'type parameter',
// which is not valid in the given context.
T.Fct();
*/
// Here is the right syntax to call Fct().
BaseClass9.Fct();
}
}
// A type used in a derivation constraint can be an open or closed generic type. Let's illustrate this using the System.IComparable<T> interface. Remember that the types which implement this interface can see their instances compared to an instance of type T.
// Note that a type used in a derivation constraint must have a visibility greater or equal to the one of the generic type which contains this parameter type. For example:
//
//
// Example 11
/*commentedouttobuild
internalclassBaseClassB{}
// Compilation Error: Inconsistent accessibility:
// constraint type 'BaseClass' is less accessible than 'C<T>'
publicclassCB<T>whereT:BaseClassB{}
*/
// To be used in a generic type, certain functionalities can force you to impose certain derivation constraints. For example, if you wish to use a T type parameter in a catch clause, you must constrain T to derive from System.Exception or of one of its derived classes. Also, if you wish to use the using keyword to automatically dispose of an instance of the type parameter, it must be constraint to use the System.IDisposable interface. Finally, if you wish to use the foreach keyword to enumerate the elements of an instance of the parameter type, it must be constraint to implement the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface.
//
//
// Take note that in the special case where T is constrained to implement an interface and T is a value type, the call to a member of the interface on an instance of T will not cause a boxing operation. The following example puts this into evidence: