Generic and generic sets in C,
1. What is generic?
Generic is a new function in the C # language and the Common Language Runtime Library (CLR). It introduces the concept of type parameters to. NET Framework. Type parameters make it possible to design certain classes and methods. For example, by using the generic type parameter T, it can greatly simplify the process of forced conversion or packing between types (the next article describes how to solve the problem of packing and unpacking ). To put it bluntly, generics are implemented to operate multiple data types on the same code by using parameterized types, and the types are abstracted using parameterized types to Achieve flexible reuse.
The use of generics brings five benefits to code: 1. Code can be reused to a large extent, security of the type can be protected, and performance can be improved.
2. You can create a collection class.
3. you can create your own generic interfaces, generic methods, generic classes, generic events, and generic delegation.
4. You can restrict generic classes to access methods of specific data types.
5. Information about types used in generic data types can be obtained through reflection at runtime.
Example:
using System;namespace ConsoleApp{ class Program { class Test<T> { public T obj; public Test(T obj) { this.obj = obj; } } static void Main(string[] args) { int obj1 = 2; var test = new Test<int>(obj1); Console.WriteLine("int:" + test.obj); string obj2 = "hello world"; var test1 = new Test<string>(obj2); Console.WriteLine("String:" + test1.obj); Console.ReadKey(); } }}
The output result is:
Int: 2
String: hello world
Analysis:
1,TestIs a generic class. T is the model type to be instantiated.If T is instantiated as int type, the member variable obj is int type. If T is instantiated as string type, obj is of the string type.
2. The above program shows different values based on different types.
2. What are the main and secondary constraints of the generic model?
Six types of constraints:
T: Structure |
The type parameter must be a value type. You can specify any value type except Nullable. For more information, see use a void type (C # programming guide ). |
T: Class |
The type parameter must be a reference type, including any class, interface, delegate, or array type. |
T: new () |
The type parameter must have a public constructor without parameters. When used together with other constraints,New ()The constraint must be specified at the end. |
T: <Base Class Name> |
The type parameter must be a specified base class or derived from the specified base class. |
T: <Interface Name> |
The type parameter must be a specified interface or implement the specified interface. Multiple interface constraints can be specified. The constraint interface can also be generic. |
T: U |
The type parameter provided for T must be provided for U or derived from U. This is called the bare type constraint. |
Example:
1. Interface constraints.
For example, you can declare a generic class MyGenericClass, so that the type parameter T can implement the IComparable <T> interface:
public class MyGenericClass<T> where T:IComparable { }
2. base class constraints.
Specifies that a type must use the specified class as the base class (or the class itself) to be used as the type parameter of the generic type. This constraint must appear before all other constraints of this type of parameter.
class MyClassy<T, U>where T : classwhere U : struct{}
3.Constructor constraints.
You can use the new operator to create an instance of the type parameter. However, the type parameter must be subject to the constructor constraints of new. The new () constraint allows the compiler to know that any type of parameter provided must have an accessible, non-parameter (or default) constructor. The new () constraint appears at the end of the where clause.
public class MyGenericClass <T> where T: IComparable, new(){ T item = new T();}
4. For Multiple type parameters, each type parameter uses a where clause.
interface MyI { }class Dictionary<TKey,TVal>where TKey: IComparable, IEnumerablewhere TVal: MyI{ public void Add(TKey key, TVal val) { }}
5. You can also attach constraints to type parameters of generic methods.
public bool MyMethod<T>(T t) where T : IMyInterface { }
6. Bare type constraints
The generic type parameters used as constraints are called Bare type constraints. When a member function with its own type parameters needs to constrain this parameter to include type parameters, the bare type constraints are useful.
class List<T>{ void Add<U>(List<U> items) where U : T {}}
Why are there constraints?
When a generic parameter does not have any constraints, the operation and operation it can perform is very limited, because it cannot guarantee any types of real parameters, in this case, generic constraints are required. Both the Primary and Secondary constraints of the generic model mean that the real parameters of the generic model must meet certain specifications. C # the compiler can check the real parameters of all generic types according to the constraints during compilation and ensure that they meet the constraints.
A generic parameter can have at most one major constraint, which can be a reference type, class, or struct. If a reference type is specified, the real parameter must be of this type or a derived type. Class specifies that the real parameter must be of a reference type. Struct specifies that the parameter must be a new one. The following code is an example of the main constraints of generic parameters.
Using System; namespace Test {class GenericPrimaryConstraint {static void Main () {Console. read () ;}/// main constraint: T inherits from the Exception type public class ClassT1 <T> where T: Exception {private T myException; public ClassT1 (T t) {myException = t;} public override string ToString () {// The main constraint ensures that myException has the Source member return myException. source ;}/// the primary constraint is that T is the reference type public class ClassT2 <T> where T: class {private T myT; public void Clear () {// T is a reference type and can be set to null myT = null; }}// the main constraint is that T is a value type public class ClassT3 <T> where T: struct {private T myT; public override string ToString () {// T is a value type, and no NullReferenceException exception return myT. toString ();}}}
In the above Code, after a generic parameter has the primary constraints, it can perform certain operations on it in the type. Otherwise, any algorithm can only be based on a member of the System. Object type.
It can be said that the main constraint is the limitation of the real parameter type, while the relative secondary constraint refers to the limitation of the interface implemented by the real parameter. For a generic type, there can be zero to unlimited secondary constraints. Secondary constraints stipulate that parameters must implement the interfaces specified in all secondary constraints. The syntax of the secondary constraint is basically the same as that of the primary constraint. The difference is that one or more interfaces are provided instead of a reference type.
Ps: Generic parameters with both primary and secondary constraints, indicating that real parameters must satisfy both primary and secondary constraints.
3. What is a generic set?
A string can be a collection of characters. Similar to a string, data objects can also exist in a set. Therefore, generic objects can also exist in a set (generic set)
Compared with traditional collections, generic collections are strongly-typed sets that solve type security problems. They also prevent each boxing and unpacking operation in the collection and improve the performance.
Generic set type:
1. List, which is the most generic type of our applications. It corresponds to the ArrayList set.
2. Dictionary. This is also a set of commonly used generic types that correspond to Hashtable.
3. Collection corresponds to CollectionBase
4. ReadOnlyCollection corresponds to ReadOnlyCollectionBase, which is a read-only set.
5. Queue, Stack, and SortedList correspond to non-generic classes with the same name as them.
Performance problems
The following uses ArrayList and List <T> as examples to describe the advantages of generic sets and the disadvantages of non-generic sets. For example, there is such a piece of code:
Using System; using System. collections; using System. collections. generic; using System. linq; using System. web; using System. web. UI; using System. web. UI. webControls; namespace Web {public partial class B: System. web. UI. page {protected void Page_Load (object sender, EventArgs e) {ArrayList numbers = new ArrayList (); numbers. add (1); // boxed numbers. add (2); // binning int number = (int) numbers [1]; // unpack Label1.Text = number. toString ();}}}
What will happen behind this code? First, all elements in the ArrayList are considered as Object types, which are reference types. The Add method is called to Add two integers. In this process, integer 1 and 2 are boxed by CLR into the object type, and the second element is unboxing ), in general, the following process occurs during packing and unpacking:
1. configure a new object in the managed heap
2. stack-based data must be moved to the memory zone that is not configured.
3. When unpacking, data in the heap must be moved to the stack.
4. Garbage collection of useless data in the heap
When a large number of packing and unpacking operations are involved, the performance of the application will inevitably be affected. Instead, the use of generic collection classes reduces the workload of packing and unpacking. When there is a large amount of data, it can naturally improve a lot of performance ., For example
Using System; using System. collections; using System. collections. generic; using System. linq; using System. web; using System. web. UI; using System. web. UI. webControls; namespace Web {public partial class B: System. web. UI. page {protected void Page_Load (object sender, EventArgs e) {List <int> numbers = new List <int> (); // find different numbers. add (1); numbers. add (2); int number = numbers [1]; // find different Label1.Text = number. toString ();}}}
Type security questions
For ArrayList, the following code will not report errors during compilation.
ArrayList numbers = new ArrayList(); numbers.Add(22); numbers.Add(35.5); numbers.Add(true); foreach (object item in numbers) { Console.WriteLine((int)item); }
Because the int, float, and other numeric types can be packed into objects, even if the data types added to the ArrayList are inconsistent. The compiler will not prompt an error, but an error will be reported during runtime.
However, if you use a generic type such as List <T>, type check is performed during compilation. Prevents running errors.
Ps: This article is based on my understanding on the Internet. If your rights and interests are inadvertently violated, please contact me.