Transferred from: http://www.cnblogs.com/kk888/archive/2011/09/01/2161647.html
The so-called generics, that is, by parameterized types to implement the same code to operate a variety of data types. Generic programming is a programming paradigm that abstracts types using "parameterized types" for more flexible reuse.
When you define a generic class, you can impose restrictions on the type types that client code can use for type parameters when instantiating a class. If the client code attempts to instantiate a class with a type that is not allowed by a constraint, a compile-time error occurs. These restrictions are called constraints. Constraints are specified using the WHERE context keyword.
The following table lists the five types of constraints:
Constraints |
Description |
T:struct |
The type parameter must be a value type. You can specify any value type other than Nullable. |
T:class |
The type parameter must be a reference type, including any class, interface, delegate, or array type. |
T:new () |
The type parameter must have a public constructor with no parameters. When used with other constraints, the new () constraint must be specified last. |
t:< base class name > |
The type parameter must be the specified base class or derive from the specified base class. |
t:< Interface Name > |
The type parameter must be the specified interface or implement the specified interface. You can specify multiple interface constraints. The constraint interface can also be generic. |
T:u |
The type parameter provided for T must be either a parameter supplied for u or a parameter derived from U. This is called a bare type constraint. |
---------------------------------------
I. Derivation constraints
1. Common
Public class where t:icomparable {}
2. Constraints are placed after the actual derivation of the class
Public class B {} Public class where t:icomparable {}
3. You can inherit a base class and multiple interfaces, and the base class is in front of the interface
public class B {}
public class myclass7<t> where t:b, IComparable, icloneable {}
Two. Constructor constraints
1. Common
public class myclass8<t> where T:new () {}
2. Constructor constraints and derived constraints can be combined, provided that the constructor constraints appear at the end of the constraint list
public class myclass8<t> where t:icomparable, new () {}
Three. Value constraints
1. Common
Public class where struct { }
2. Used in conjunction with interface constraints at the top (cannot be used with base class constraints, constructor constraints)
Public class where struct, IComparable {}
Four. Referential constraints
1. Common
Public class where class { }
Five. Multiple generic parameters
Public class where T:icomparable whereclass {}
Six. Inheritance and generics
Public class b<t>{}
1. When deriving from a generic base class, you can provide a type argument instead of a base class generic parameter
Public class subclass11:b<int> {}
2. If the subclass is generic, not a specific type argument, you can use the subclass generic parameter as the specified type of the generic base class
Public class Subclass12<r>: b<r> {}
3. Repeat the constraints of the base class in the subclass ( when using a subclass generic parameter, you must repeat any constraints specified at the base class level at the subclass level)
Public class where t:isomeinterface {} Public class where T:isomeinterface {}
4. Constructor constraints
Public class where New () { public T somemethod () { return New T (); } } Public class where New (){ }
Seven. Generic method (the c#2.0 generic mechanism supports "include type parameters in the method's reputation", which is the generic method)
1. Generic methods can be contained in both generic types and non-generic types
Public class MYCLASS5 { publicvoid mymethod<t>(T-t) {} }
2. Declaration and invocation of generic methods
Public class MYCLASS5 { publicvoid mymethod<t>(T-t) { } }publicclass App5 { publicvoid Callmethod () { new MyClass5 (); Myclass5. MyMethod<int> (3); } }
3. Overloading of generic methods
First set of overloads
void mymethod2<t> (intvoid MyMethod2 (int i) {}
Second set of overloads
Public class Myclass8<t,u> { public T mymothed (t A, U B) { return A; } Public T mymothed (U A, T b) { return b; } Public int mymothed (intint b) { return a + b; } }
The following overloads are incorrect:
// first set of overloads void int voidint i) {}/// Second set of overloads, assuming there are two generic parameters voidwhere t:a {}voidwhere t:b {}
4. Override of generic methods
(1) Public classMyBaseClass1 { Public Virtual voidMymothed<t> (T t)whereT:New() { } } Public classMysubclass1:mybaseclass1 { Public Override voidMymothed<t> (T t)//cannot repeat any constraints { } }(2) Public classMyBaseClass2 { Public Virtual voidMymothed<t>(T t) {}} Public classMysubclass2:mybaseclass2 { Public Override voidMymothed<t> (T t)//redefine generic parameter T { } }
Eight. Virtual methods
Public classBaseclass4<t> { Public VirtualT SomeMethod () {return default(T); } } Public classsubclass4:baseclass4<int>//when using arguments for inheritance, the method uses the type of the argument { Public Override intSomeMethod () {return 0; } } Public classSubclass5<t>: baseclass4<t>//when using generic inheritance, the method is also generic { Public OverrideT SomeMethod () {return default(T); } }
Nine. The compiler allows only generic parameters to be implicitly cast to Object or to the type specified by the constraint
class where T:baseclass, ISomeInterface { void SomeMethod (T-t ) {= t ; = T; object obj3 = t; } }
Workaround: Use a temporary Object variable to cast the generic parameter to any other type
class Myclass2<t> { void SomeMethod (T-t ) {object temp = T; = (baseclass) temp; } }
10. The compiler allows you to explicitly cast a generic parameter to any other interface, but you cannot convert it to a class
class Myclass1<t> { void SomeMethod (T t) { = (isomeinterface) t; // BaseClass obj2 = (baseclass) t; // cannot be compiled by } }
11. Use the temporary Object variable to cast the generic parameter to any other type
class Myclass2<t> { void SomeMethod (T-t ) {object temp = T; = (baseclass) temp; } }
12. Using the IS and as operators
Public classMyclass3<t> { Public voidSomeMethod (T t) {if(t is int) { } if(t islinkedlist<int>) { } stringstr = t as string; if(str! =NULL) {} LinkedList<int> list = t aslinkedlist<int>; if(List! =NULL) { } } }
"Go" C # generic constraint