The delegate parameter is used to parameterize the method, while the generic parameter is used to parameterize the type.
I. Rules for declaring generic types:
1. The class name is followed by a pair of angle brackets. There are several type parameters in the brackets. Multiple type parameters are separated by commas. type parameters are actually type placeholders. For example, public class myclass <t >{} and T are just a habit. In fact, they can use other letters.
2. Use the type parameter in the body of the class declaration to indicate the type to be replaced. It is generally the type of the method parameter, the return type, or the type of the field or attribute.
Example 1:
Public class myclass <T1, T2> {public T1 field1; // you can use public T2 field2 or public T1 getfield1 () in the generic type of the class () // return value {return field1;} public T2 getfield2 () {return field2;} public void setfield1 (T1 data) // as the method parameter type {field1 = data ;} public void setfield2 (t2 data) {field2 = data ;}}
Generics can implement different processing based on different input types. The Code logic is reused to abstract the type.
For generic type constraints, certain constraints can be added to type arguments through constraints. constraints are applied by where context keywords are used, you only need to use the where keyword after the angle brackets of the generic type declaration, followed by the type parameter and the constraint type, separated by a colon in the middle.
There are 6 types of constraints, as shown below:
| Constraint type |
Description |
| Where T: Class |
The type real parameter must be of the reference type, including any class, interface, delegate, or array type. |
| Where T: struct |
The type real parameter must be a value type, which can be any value type, but does not include nullable |
| Where T: <Base Class Name> |
The type must be the specified class or its derived class. |
| Where T: <Interface Name> |
The type must be an interface or an interface type. Multiple interface constraints can be specified, and the restricted interface can be generic. |
| Where T: New () |
The type real parameter must have a public constructor without parameters. |
| Where T: u |
The type real parameter T must be the type real parameter U or the derived class of U, which is called the bare type constraint. |
You must also note that when you need to add multiple type constraints, the constraints are separated by commas. For multiple constraints of a type parameter, the where clause and the where clause do not have order requirements, but there are internal order requirements for the WHERE clause. The specific order is as follows:
- If there are class, struct, and base class constraints, they must be placed first.
- Followed by interface constraints, unlimited quantity
- If new () exists, it must be placed at the end.
For example:
Public class testtype <t, V> where T: person where V: New () {}// there is no order for the where and where statements. Public class testtype <t> where T: class, ilist, new () {}// the WHERE clause has internal type requirements.
Class program {static void main (string [] ARGs) {person P = new person (); p. id = 1; p. name = "Zhang San"; testtype <person> TT = new testtype <person> (); string STR = TT. getType (p); console. writeline (STR); // output three consoles. readkey () ;}} public class testtype <t> where T: person // specifies that the real parameter type must be a derived class of the person class or the person class {Public String GetType (t data) {return data. name ;}} public class person {public int ID; Public string name ;}
Generic methods are similar to generic classes. Here are two examples of generic methods.
Class program {static void main (string [] ARGs) {person P = new person (); p. id = 1; setname <person> (p); console. writeline (P. name); // output Zhang Fei console. readkey ();} public static person setname <t> (t per) where T: person {per. name = "Zhang Fei"; return per;} class person {public int ID {Get; set;} public string name {Get; Set ;}} class program {static void main (string [] ARGs) {string STR = "Hello! "; Console. writeline (getmessage <string> (STR); // output system. string console. readkey ();} public static type getmessage <t> (T message) {return message. getType ();}}
The generic extension method is just a little weird like the extension method. Example:
Class program {static void main (string [] ARGs) {person <string> Per = new person <string> (); Per. person <string> ("Guan Yu"); // you can call the extension method in this way. writeline (Per. name); console. readkey () ;}} public static class set {public static void person <t> (this person <t> P, T name) {P. name = Name ;}} public class person <t> {public int ID {Get; Set ;}public t name {Get; Set ;}}
Generic delegation and non-generic delegation are similar. They only abstract the operation types and return value types involved in the process to type parameters, this delegate can be reused to a greater extent.
Public Delegate t printdelegate <t> (t data); Class program {static void main (string [] ARGs) {printdelegate <string> strdelegate = pstring; // defined in the delegate, the three major T values are string outstr = strdelegate ("I am a soldier"); // call the delegate console. writeline (outstr); // return value of the output delegate. I am a soldier and I am a soldier. printdelegate <int> intdelegate = pint; // if the type parameter is set to int, the parameter type is returned, all are int outint = pint (3); // because the parameter type is set to int, you can only bind the method console with the parameter and return value as Int. writeline (outint); // output 6 console. readkey () ;}public static string pstring (string Str) {return STR + STR ;}public static int pint (int I) {return I + I ;}}
Generic covariant and invert