157 suggestions for writing high-quality code to improve C # programs-Recommendation 32: always give priority to generics,
Recommendation 32: always give priority to generics
Generics have many advantages. both generic and generic methods have the reusability, type security, and high efficiency features at the same time, this is not possible for non-generic and non-generic methods.
Take reusability as an example:
Class MyList {private int [] items; public int this [int I] {get {return items [I];} set {this. items [I] = value ;}} public int Count {get {return items. length ;}}// omit other methods}
This type only supports integer types. If you want the type to support strings, you can redesign a class. However, the attributes and methods of these two types are very similar. If there is a method that allows the type to receive a common data type, the code can be reused, at the same time, only one type is enough. This is a function completed by generics. Generic implementation:
Class MyList <T> {private T [] items; public T this [int I] {get {return items [I];} set {this. items [I] = value ;}} public int Count {get {return items. length ;}}// omit other methods}
T can be understood as a placeholder. In the IL code generated by C # Generic compilation, T is a placeholder role. During runtime, the real-time Compiler (JIT) replaces T with the T type entered in the actual code, that is, in the local code generated by JIT, the actual data type is used. MyList <T> and MyList <T> are considered as two different types. However, this is only for local code and corresponds to the actual C # code, which only has one type, that is, the generic type MyList <T>.
If you do not need generics, another method is to design the MyList encoding from the object perspective. In the C # world, all types (including value type and reference type) are inherited from the object. If MyList is generic enough, you need to make MyList encoded for the object. The Code is as follows:
Class MyList {private object [] items; public object this [int I] {get {return items [I];} set {this. items [I] = value ;}} public int Count {get {return items. length ;}}// omit other methods}
This will allow the following code to be compiled:
List [0] = 123;
List [1] = "123 ";
The problem caused by the above two lines of code is non-type security. To ensure type security, the program can filter out some bugs during compilation. At the same time, the code can also avoid performance loss caused by "transforming to object type" or "transforming from object to actual type. Especially when the operation type is value type, it will also bring about the performance loss of packing and unpacking.
Generics bring revolutionary changes to the C # language. Many functions after FCL are implemented with generics, such as LINQ. With the help of generics and extension methods, LINQ effectively enriches the query functions of the Set, avoids code explosion and improves operation performance. When designing our own types, we should fully consider the advantages of generics and turn our own types into generic classes.