A piece of code every day-talk about generics and code generics
What is generic
Assume that you have an algorithm and the code is as follows:
static int Calculate(int number1, int number2) { return number1 + number2; }
Now, you need to add support for double type in your project. So Easy !!!, You cleverly copied the above Code, and changed all the int values to double.
static double Calculate(double number1, double number2) { return number1 + number2; }
Then your code needs to support new types, such as short, byte, string, float ..., you can't stand pressing Ctrl + C, Ctrl + V,
So what can we do without repeating this kind of work? Is the main character of today-C # generic features. Generics allow us to declare code for Type parameterization. We can instantiate it with different types, just as we have created a template for all types, then, when a type is actually used, we apply this type. Let's look at an example,
Now let me try another type.
It still works well. Let's take a look at the code in Sort <T>. There is no specific type in it.
1 public static void Sort<T>(T[] array) {2 if (array==null)3 throw new ArgumentNullException("array");4 Contract.EndContractBlock();5 Sort<T>(array, array.GetLowerBound(0), array.Length, null);6 }
In C #, generic classes, structures, interfaces, delegation, and methods are supported. The declaration method for generics and non-generics is similar, but it only has a type parameter, for example, the following code
class SomeClass<T> { public T t; //... }
1 // generic interface 2 interface IFly <T> 3 {4 void Fly (T input); 5} 6 7 class SomeClass: IFly <int> 8 {9 # region IFly <int> member 10 11 public void Fly (int input) 12 {13 Console. writeLine (input); 14} 15 16 # endregion17}
// Generic delegate R OnSubmintHandle <T, R> (T value); // It is also common to delegate Action without return values <> and delegate Func with return values <>
1 static void Main (string [] args) 2 {3 // we can use the following two methods to call the generic method, because the compiler can infer the type parameter 4 Display <int> (10), 5 Display (5), 6} 7 8 static void Display <T> (T inpute) through the method parameter) 9 {10 // some input operations 11 //..... 12}
Constraints on generic parameters
If generics are so powerful, can all type parameters be used as generic parameters?
1 // compare two numbers and return a smaller 2 static T Min <T> (T t1, T t2) where T: IComparable <T> 3 {4 return t1.CompareTo (t2)> 0? T2: t1; 5}
In this Code, you may notice where T: IComparable <T>. What is this? Why should I add this code? After I remove this code, visual prompts an error.
It can be seen that not all of them can be used as generic type parameters, unless your generic type does not have any operations in it. So how can we constrain generic type parameters? This uses the key where
class SomleClass<T, U, R> where T : class where U : IComparable { }
Constraint type table:
Class Name |
Only a class of this type or a class inherited from it can be used as a type parameter. |
Class |
Any reference type, including classes, arrays, delegates, and interfaces, can be used as real parameters. |
Struct |
Any value class can be used as a type argument. |
Interface |
Only this interface or the type that implements this interface can be used as a real parameter. |
New () |
Any type of constructor with no parameters can be used as real parameters. constructor constraints must be placed at the end of all constraints. |
If there are multiple constraints at the same time, they need to be arranged in a certain order
// Constraint sequence: [class, class, struct], [interface], [new ()] class SomleClass <T, U, R> where T: class, IComparable, new (){}