Eat lunch before the general and then write an article about generics, although the blog is always moved first page, the article is really a big problem ah, will redouble their efforts. Go to the chase.
First, the generic constraint. When we use generics, we usually want to use generic arguments that have certain properties, and then "generic constraints" come in, which can help us pass in the generic parameter, which implements the previously specified constraint. There are 4 types of constraints available, as follows:
- Reference type constraint: Ensure that the type parameter used is a reference type (T:class, and must be the first constraint specified by the type parameter), that the type argument is any class, interface, array, delegate, or another type parameter that is known to be a reference type.
- Value type constraint: expressed as (t:struct), you can ensure that the argument used is a value type, including an enumeration (enums), but that it queues nullable types in the outside.
- Constructs a type constraint: represented as (T:new ()), which must be the last constraint of the constraint, which checks whether the type has an parameterless constructor that can be used to create an instance.
- Conversion type constraint: Allows you to specify another type, which can be converted to that type by a consistency reference or an implicit conversion or boxing conversion.
1 Public structDodo<t>whereT:class2 {}3 Public classBibi<t>whereT:struct4 {}5 Public structCoco<t>whereT:New()6 {}7 Public structDkdk<t>whereT:System.Data.IDbConnection8{}
The above four correspond to four types of constraints (only in a single use), below the case of combination use.
The combination uses two points to note:
- If there are multiple rotation type constraints, and one of them is a class, it should appear in front of the interface and cannot be specified more than once.
- When more than one type parameter is included, each type constraint uses a single where.
1 //You cannot specify both a reference type and a value type for a type parameter2 //Public struct dodo<t> where t:class, struct3 //{}4 5 Public classBibi<t>whereT:stream,New()6 {}7 8 //using the construct type constraint, new () is placed in the last9 //Public class lili<t> where T:new (), StreamTen //{} One A Public structCoco<t>whereT:class, IDisposable,New() - {} - the //The following constraint is a class, to be placed in front of the interface - //Public struct fefe<t> where t:idisposable, class, New () - //{}
The use of generic constraint knowledge is above, more to understand and digest. When using a generic method, let the compiler be inferred to make our code shorter, but the readability may not be high.
--------------------------------------------------------------------------------------------------------------- ---------------------------
Point 1 for static fields and static construction methods, each enclosing type has a static field, if any
1staticconstraint<int> intstatic =Newstaticconstraint<int>();2staticconstraint<int. Staticvalue ="int";3 4staticconstraint<Double> doublestatic =Newstaticconstraint<Double>();5staticconstraint<Double. Staticvalue ="Double";6 7staticconstraint<Char> charstatic =Newstaticconstraint<Char>();8staticconstraint<Char. Staticvalue ="Char";
Point 2 using typeof to get types
typeof can act on a generic type in two ways, one to get an unbound generic type, and one to get a specific constructed type. The first one needs to provide the name of the generic, to remove the names of all type parameters, but to preserve the comma, the latter need to take the same way as declaring a generic type variable to specify the type parameter.
1 Static voidGettypeofconstraint<x>()2 {3 //get unbound generic type4Console.WriteLine (typeof(X));5Console.WriteLine (typeof(list<>));6Console.WriteLine (typeof(dictionary<,>));7 8 //Get constructed type9Console.WriteLine (typeof(list<int>));TenConsole.WriteLine (typeof(dictionary<int,Double>)); One}
Please treatise.
06.c# generic Constraints and Advanced Generics (Chapter three 3.3-3.4)