Generic Overview
Generic is a type of polymorphism. For example, when we write a stack or queue, We need to specify its data type, intCode, String, and object. Except for different data types, most of the Code is the same. According to the design pattern, it is abstracted to encapsulate the change point, the common part serves as the shared code. The change point here is the type, and the common part isAlgorithmSame, so the type is abstracted, so the generic model is available & [personal understanding].
C # generics are supported by CLR at runtime, which enables seamless collection of generics in various languages supported by CLR; C # When the [first compilation] of generic code is Il code and metadata, the [generic version of Il and metadata] uses special placeholders to represent generic types, the proprietary il commands are used to support generic operations. The real generic instantiation occurs during JIT compilation [Second compilation. When the JIT compiler encounters this special Il and metadata for the first time, it will replace [instantiation of generic types] with the actual types. CLR generates the same code for all type parameters that reference the generic type. For value types, different value types generate different codes. For the same value type, the same code is shared.
C # generic types carry rich metadata, So C # generic types can be applied to powerful reflection technologies. They use [base classes, interfaces, constructors, value Type/reference type] constraints to achieve "Explicit Constraints" on type parameters, improve type security. Demo:
Public ClassMytype <t>WhereT:Struct{PrivateT [] _ items;Public VoidAdd (T itme ){}}
After compilation, Il is as follows:
// Generic class <'1 indicates the number of elements or the number of parameters> . Class Public Auto ANSI Beforefieldinit Mytype'1 <Valuetype. ctor // Note that the wildcard constraint <[mscorlib] system. valuetype) T> is added here. // Indicates that the type parameter is of the value type. ([Mscorlib] system. valuetype) T> Extends [Mscorlib] system. object {} // End of class mytype '1 // This is the private field . Field Private ! T [] _ items // Add method, type parameter <t> there is an exclamation point before <!>, This is the beginning of the rule to support generics. // It indicates the existence of the first type parameter specified for the class, indicating that this is // One type parameter . Method Public Hidebysig Instance Void Add (! T itme) Cel Managed { // Code size 2 (0x2) . Maxstack 8 Il_0000: NOP Il_0001: RET } // End of method mytype '1: add
In addition to these differences, there is no big difference between the generic and non-generic types in the template code.
Generic Type and generic Method
Generic types include classes, interfaces, structures, and delegation.
C # supports generic methods, but does not support attributes, events, indexers, constructors, and destructor of other members except methods. However, these members can be included in the generic type and use the generic type parameters]. The generic method can be included in the generic type, it can also be included in a non-generic type [normal type]. Generic method:
Public Class Genericsmehod { // Generic methods in non-generic classes. The parameter constraints are reference types. // <A compilation error occurs when a value type parameter is input.> Public Int Finditem <t> (T [] items, t item) Where T: Class { For ( Int I = 0 ; I <items. length; I ++){ If (Items [I]. Equals (item )){ Return I ;}} Return - 1 ;}}
You do not need to write for the call. generic methods support overloading, but the overload of the parameter constraints of different types is invalid. It also supports rewriting. The type parameter constraints during rewriting are inherited by default, it is unnecessary to specify any constraints.
Generic Constraints
Why are there constraints? If I write a generic class, this generic parameter calls the compareto method, but not all type parameters have this method, if the input type does not have this method, this will cause errors. To ensure the robustness of your code, it is necessary to add constraints. [that is to say, the input type must have this method before it can be compiled, expose errors to the compilation stage]. Generic constraints support four types of constraints: interface constraints, base class constraints, constructor constraints, value type constraints, and reference type constraints. constraints are not mandatory. If no constraints are specified, the type parameter can only access system. public methods in object type. Syntax: Where statement
The preceding type parameter requires a compareto method and can be implemented using an interface constraint:
Public ClassMygenerics <t>;WhereT: icomparable {}
Base class constraints: If a table is a type parameter, it must be an inherited sub-specified type <where T: base class>;
Constructor constraints: Only constructor constraints without parameters are supported. It must ensure that the parameter type can be called by its non-parameter constructor <where T: New ()>:
Value Type/reference type constraints: there are only two cases: <where T: struct> or <where T: Class>. The specified parameter type must be a value or reference type;