Finally the generics. When I first saw the title, I wanted to see the author's understanding of the concepts of generics, entrustment, and reflection. A lot of people's understanding of generics stays on the generic set, and at first I also, as the project more and more, the understanding of generics is more and more profound.
Generic concept: Generics are a special type that defers the work of a specified type until the client code declares and instantiates a class or method.
The benefits of generics: Source code protection, type safety, clearer code, better performance.
Principle: (Keywords: open type, enclosing type) all types with generic parameters are an open type, it cannot be instantiated (like interfaces), and the enclosing type (actual data type) is generated when it is used in concrete form.
Generic constraints (up to one primary constraint, no limit for minor constraints):
Use of generic constraints:
/// <summary> ///Unconstrained T can be any type, many types do not provide a CompareTo method, no constraints will cause code not to compile, the "' t ' does not contain ' CompareTo ' definition" error/// </summary> /// <typeparam name= "T" ></typeparam> /// <param name= "O1" ></param> /// <param name= "O2" ></param> /// <returns></returns> Private StaticT min<t> (t o1,t O2)whereT:icomparable<t> { if(O1.compareto (O2) <0)returnO1; returnO2; }
Constructor constraints:
// because all value types implicitly have a public parameterless constructor. Constraints require that any reference type specified also have a public parameterless constructor internalsealedclasswhere T:new() { publicstatic T Factory () { returnnew t () ; }}
Because generic type parameters cannot specify the following special reference types: System.object,system.array,system.delegate,system.multicastdelegate,system.valuetype, System.enum,system.void, some implementations of the actual parameter restrictions may be "special handling", as the following uses a static constructor to ensure that the type is an enumeration type.
Internal Sealed class Generictypethatrequiresanenum<t>{ static generictypethatrequiresanenum () { if(! typeof(T). Isenum) { thrownew ArgumentException ("T must is an enumerated type "); } }}
The benefits of a generic interface: There is no generic interface, and each time the view uses a non-generic interface to manipulate a value type, boxing occurs and the compile-time type security is lost.
Inverse and covariant generic type arguments for delegates and interfaces:
Invariant: means that the generic type parameter cannot be changed. Common
Inverse variable: means that a generic type parameter can be changed from a base class to a derived class of that class. In C #, use the IN keyword to mark generic type parameters in the form of an inverse variable. The inverse variable generic type parameter appears only in the input position, such as as a parameter to the method.
Covariance: means that a generic type parameter can be changed from a derived class to its base class. In C #, a generic type parameter is marked with the Out keyword as the HKJA variable. The covariant generic type parameter can only appear in the output location, such as the return type of the method.
Public Delegate TResult func< in T, out tresult> (t arg);
Other important perceptions:
There is no relationship between the designation of a type argument and the inheritance hierarchy-understanding this can help you judge the transition.
C # allows the use of simplified syntax to reference a generic enclosing type
using Datetimelist = system.collections.generic.list<system.datetime>;
Now that the following line of code is executed, Sametype is initialized to true:
Boolean Sametype = (typeoftypeof(datetimelist));
The CLR supports generic delegates to ensure that any type of object can be passed to a callback method in a type-safe manner. In addition, a generic delegate allows any instance of a value type to not perform any boxing processing when passed to a callback method.
Some validation issues:
1. Transformation of generic type variables
It is illegal to convert a variable of a generic type to another type unless it is transformed into another constraint-compatible type
Private Static void Castingtype<t>(T obj) { = (Int32) obj; Error String s = (String) obj; Error string as String; no Error }
2. Set Default values
Private Static void Settingdefaultvalue<t>() { default(T);}
The default keyword tells the C # compiler and the CLR's JIT compiler that if T is a reference type, TEMP is set to NULL, and if T is a value type, all bits of temp are set to 0.
"Clr.via.c# Third Edition" Part II 12th chapters Generic reading notes (vi)