CLR. via. C # Part 2 Part 2 Section 12th generic Reading Notes (6 ),
Finally, we talked about generics. When I first saw this title, I wanted to see the author's understanding of generic, delegate, and reflection concepts. Many people's understanding of generics remains on the generic set. At the beginning, I started to understand generics more and more.
The concept of generics: generics are a special type that delays the work of a specified type until the client Code declares and instantiates a class or method.
Advantages of generics: source code protection, type security, clearer code, and better performance.
Principle: (Keyword: Open Type, closed type) All types with generic parameters are open types and cannot be instantiated (similar to interfaces ), generate a closed type (actual data type) for specific use ).
Generic constraints (up to one major constraint, but not limited to secondary constraints ):
Use of generic constraints:
/// <summary>
/// Unconstrained T can be of any type, and many types do not provide a CompareTo method. Without constraints, the code cannot be compiled, and an "" T "does not contain the definition of" CompareTo "" is reported
/// </ summary>
/// <typeparam name = "T"> </ typeparam>
/// <param name = "o1"> </ param>
/// <param name = "o2"> </ param>
/// <returns> </ returns>
private static T Min <T> (T o1, T o2) where T: IComparable <T>
{
if (o1.CompareTo (o2) <0) return o1;
return o2;
}
Constructor constraints:
// Because all value types implicitly have a public no-argument constructor. Constraints require that any reference type specified also have a public no-argument constructor
internal sealed class ConstructorConstraint <T> where T: new () {
public static T Factory () {
return new 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, the implementation of some argument restrictions may be "special Processing ", such as the following using a static constructor to ensure that the type is an enumerated type.
internal sealed class GenericTypeThatRequiresAnEnum <T> {
static GenericTypeThatRequiresAnEnum () {
if (! typeof (T) .IsEnum) {
throw new ArgumentException ("T must be an enumerated type");
}
}
}
Advantages of generic interfaces: Without generic interfaces, every time a view uses a non-generic interface to manipulate a value type, boxing will occur, and compile-time type safety will be lost.
Inverter and covariant generic type arguments for delegates and interfaces:
Invariant: Means that generic type parameters cannot be changed. (Commonly used)
Inverse quantity: 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 a generic type parameter in the form of an inverter. Inverter generic type parameters only appear at the input position, for example as method parameters.
Covariate: Means that a generic type parameter can be changed from a derived class to its base class. In C #, a generic type parameter in the form of a covariate is marked with the out keyword. Covariate generic type parameters can only appear in output locations, such as the return type of a method.
public delegate TResult Func <in T, out TResult> (T arg);
Other important cognitions:
The specification of type arguments has nothing to do with the inheritance hierarchy-understanding this helps you judge the transition.
C # allows to use a simplified syntax to reference a generic closed type
using DateTimeList = System.Collections.Generic.List <System.DateTime>;
Now when the following line of code is executed, sameType is initialized to true:
Boolean sameType = (typeof (List <DateTime>) == typeof (DateTimeList));
The CLR supports generic delegation in order to ensure that any type of object can be passed to a callback method in a type-safe manner. In addition, generic delegates allow any value type instance to not perform any boxing when passed to a callback method.
Some verification issues:
Transformation of generic type variables
It is illegal to cast a variable of a generic type to another type, unless it is cast to another constraint-compatible type
private static void CastingType <T> (T obj) {
Int32 x = (Int32) obj; // Error
String s = (String) obj; // Error
string s2 = obj as String; // No error
}
2. Set the default value
private static void SettingDefaultValue <T> () {
T temp = default (T);
}
The default keyword tells the C # compiler and the CLR JIT compiler to set temp to null if T is a reference type, and to set all the bits of temp to 0 if T is a value type.