2005.8.10 Li Jianzhong
Agenda
C # generics and mechanisms
Generic Type
Generic Method
Generic Constraints
Lecture Summary
C # Generic demonstration
We can also directly use the object type. However, due to performance issues and type security issues, generics are a better choice.
In the generic type, T is a generic type parameter, which is bound late. During C # compilation, the T type is not determined.
C # Introduction to generics
If we do not replace T with a specific int, It is a high-level abstract type, which cannot be used. It must be instantiated by the generic type to become a specific type.
The so-called generic type means that multiple data types can be operated on the same code using parameterized types. Generic programming is a programming paradigm that abstracts types by using parametric types to achieve more flexible reuse.
This is actually a type of polymorphism.
C # generics give stronger codeType security, better reuse, and higher efficiency, More clear constraints.
C # Introduction to generic mechanisms
C # The generic capability is supported by CLR at runtime. It is different from the C ++ compile-time template mechanism, and from the Java compile-time "batch erase ". This enables seamless interoperability between languages that support CLR.
All generic processing in C ++ is performed during compilation, and no generics are visible at runtime. Only specific types can be seen, because it has processed all generics during compilation. Java generics cannot achieve higher efficiency, but they are still expressed using objects. C # generics are supported during runtime
C # When the generic code is compiled as the IL code and metadata, special Placeholders are used to represent the generic type, and proprietary IL commands are used to support generic operations. WhileReal generic instantiationWork"On-demand"(As needed,Occurs during JIT compilation
Generic IL code and metadata
The Stack on the left is the compiled generic type, T is not instantiated, And the void method on the right instantiates the generic type. newobj can be called only after the instantiated generic type.
C # Generic compilation Mechanism
During the first round of compilation, the compiler only generates the "generic version" IL code and metadata for the Stack <T> type-it does not instantiate the generic type, and T acts as a placeholder in the middle.
During JIT compilation (only the code used is JIT compiled), when the JIT compiler encounters a Stack <int> for the first time, replace the "generic version" IL code with int and the T in the metadata to instantiate the generic type.
This type is dynamically generated in the memory. If you encounter a Stack <int> for the second time, you do not need to instantiate it again, but if it is a Stack <byte>, A new type is generated in the memory.
CLR is generated for all generic types whose type parameters are "reference type"Same copyCode, but if the type parameter is "Value Type", for each different "Value Type", CLR will generateOne copyIndependent code
This is actually similar to the callback wipe method of Java. The reference type itself does not save the value of the variable, but only saves the address. It references only objects stored in the managed heap. If the Stack generic type is a reference type, its type is always the value of a memory address, because the reference type determines the number of places T represents, 32-bit machines are 32-bit and 64-bit machines are 64-bit. Therefore, the reference type only shares the same code. The efficiency is not affected by the use of the wipe method. (The efficiency of Java value types will also be affected by using the batch wipe method)
C # characteristics of generics
If the parameters of the instantiated generic type are the same, the JIT compiler will reuse this type, therefore, the dynamic generic capability of C # avoids code expansion problems caused by C ++ static templates.
C # generic types carry rich metadata, So C # generic types can be applied to powerful reflection technologies.
The generic type of C # adopts the "base class, interface, constructor, value type/reference type" constraint to implement the "display constraint" on type parameters ", this improves the type security, and also loses the high flexibility of the C ++ template based on the "signature" implicit constraint.
C # generic classes and structures
C # besides declaring generic types (including classes and structures), you can also include the declaration of generic types in the base class. However, if a base class is a generic class, its type parameters are either instantiated or derived from the type parameters declared by the subclass (also generic type.
Generic Type members
Generic Type members can use the type parameters in the generic type declaration. If the type parameter has no constraints, only public members inherited from System. Object can be used for this type.
Generic Interface
Generic Delegation
Generic delegation supports applying parameter types to delegate return values and parameters. These parameter types can also be subject to legal constraints.
Introduction to generic methods
C # The generic mechanism only supports "containing type parameters in method declaration"-that is, generic methods.
C # The generic mechanism does not support the inclusion of type parameters in declarations of other members except the method (including attributes, events, indexers, constructors, and Destructors, however, these members can be contained in generic types and use generic type parameters.
Generic methods can be included in both generic and non-generic types.
Declaration and call of generic methods
The Finder class is not a generic class, but it carries a generic method, because the method requires generic parameters. When instantiating a generic type, the generic parameters are placed behind the method, rather than behind the class.
Overload of generic methods
Override of generic methods
The constraint will be inherited by default during rewriting, and it is not feasible to add new constraints.
Introduction to generic Constraints
C # any assumption of "all generic type or generic method type parameters" must be based on "display constraints ", to maintain the type security required by C.
"Display constraint" is expressed by the where clause. You can specify "base class constraint", "interface constraint", and "constructor constraint ", there are four types of constraints: Value Type and reference type constraint.
"Display constraint" is not mandatory. If "display constraint" is not specified, generic parameters can only access public methods in the System. Object type.
C # puts the instantiation at runtime, which is different from the C ++ template. C ++ can check constraints during compilation. If C # is checked only when JIT is used, the method cannot be found. Therefore, C #'s constraints are closely related to its dynamic instantiation mechanism.
Base Constraint
Interface Constraints
Constructor Constraints
C # Only constructors without parameters are supported. The constructor constraint is mainly used to ensure that the passing parameterized type may use its objects.
Value Type/reference type constraints
Lecture Summary
The generic capability of C # is supported by CLR at runtime. It is different from the static template supported by C ++ during compilation, it is also different from the simple generic type supported by Java's use of the "batch wipe" method at the compiler level.
C #'s generic support includes class, structure, interface, delegation, and method members.
The generic type of C # adopts the "base class, interface, constructor, value type/reference type" constraint to implement the "display constraint" on type parameters ", it does not support signature-based implicit constraints like the C ++ template.
2010.10.26