The definition of a delegate is similar to that of a method, but a delegate is added before the return value type. For example, public delegate void prientdelegate (string content) is actually a delegate that can encapsulate a method into a reference type and be passed like a common object.
I. Considerations for delegation statement
1. Like a class, a delegate declaration can be a class of external declarations, or a delegate can be a class of internal declarations.
2. Although the form of the delegate statement is similar to that of the method, it does not have a method subject, but directly ends with a semicolon.
3. modifiers can be new, public, protected, internal, and private.
4. After the delegate keyword, it is the method signature that can be matched by the delegate type. In particular, it also includes the return type of the method, but it does not exactly match the method name.
2. Two requirements must be met when binding a method to a delegate
1. The method signature must be the same as the delegate signature. The number and type of method parameters.
2. the return value type of the method must be the same as that of the delegate.
Calling a delegate is equivalent to calling the method bound to the delegate. A delegate can bind multiple methods. The delegate is a reference type, so it can be passed everywhere. Without it, can C # pass methods everywhere?
Attach a basic example
Public Delegate void print (string Str); // declare a delegate class program {public static void printstring (string Str) {console. writeline (STR);} static void main (string [] ARGs) {// create a delegate object and assign the printstring Method to the delegate print P = new print (program. printstring); // print P = program. printstring; // use the = sign directly to bind the delegate method. P ("the call delegate actually calls the method bound to the Delegate! "); // The output call delegate actually calls the method bound to the Delegate! Console. readkey ();}}
3. Combination of delegates (relationship between multiple delegates)
"+" Can be used to combine two delegates. "-" can be used to delete one member from a delegate combination.
Public Delegate void print (); Class program {public static void printstring1 () {console. writeline ("I am the first method");} public static void printstring2 () {console. writeline ("My second method");} static void main (string [] ARGs) {// create a delegate object and bind the method print p1 = program. printstring1; // delegate the P1 binding method 1 print P2 = program. printstring2; // delegate P2 binding method 2 print P3 = p1 + P2; // combine P1 and P2 to form a new delegate P3 P3 (); // call delegate P3, it is equivalent to calling all the methods already bound to P3. In this case, it is method 1 and method 2. In this case, the output is the first method "line feed" and the second method is print P4 = P3-P1; // create a new delegate object. The binding method is the P3 delegate combination to remove the delegate P1. Actually, only P2 P4 () is left. // call the delegate P4, it is equivalent to calling all the methods bound to P4. I am the second method console. readkey ();}}
4. add and delete a delegate (a delegate)
You can use the "+ =" operator to add a new method for binding a delegate, and use "-=" to delete a bound method from the delegate.
Public Delegate void print (); Class program {public static void printstring1 () {console. writeline ("I am the first method");} public static void printstring2 () {console. writeline ("My second method");} static void main (string [] ARGs) {print P = printstring1; // declare a delegate and bind the first method P (); // call the delegate P output I am the first method P + = printstring2; // bind another method P () to P; // call the delegate P to output I am the first method "line feed" I am the second method, as you can see, once delegate P is bound to two methods, p-= printstring1; // delete a bound method P1 from delegate P; P (); // call the delegate P output. I am using the second method. Now, we can see that P is bound only to the second method. readkey ();}}
5. Application of delegation in callback
Delegate calls in the callback function:
Public Delegate void printcompletecallback (string message); Class program {public static void printmessage (string message) {console. writeline (Message);} static void main (string [] ARGs) {printcompletecallback completecallback = program. printmessage; // create a delegate and bind the printmessage method printer = new printer ("I Am a printer"); printer. print (completecallback); // call the print method of the P object. A delegate must be input as a parameter, which is equivalent to passing a method as the parameter console. readkey () ;}} public class printer {private string _ name; Public printer (string name) {_ name = Name;} public void print (printcompletecallback callback) // The delegate object is used as the method parameter {callback (_ name + "printed"); // call the delegate, which is equivalent to calling the object bound to the callback delegate }}
Vi. Anonymous Method
The biggest advantage of the anonymous method is that it reduces the system overhead and is defined only when the method is used by delegation. Passing a piece of code directly to the delegate is easier than creating a method first and then binding it to the delegate.
Rules for using anonymous methods:
1. The jump statement cannot be used in the anonymous method to jump to the external side of the anonymous method, and vice versa. The jump statement outside the anonymous method cannot jump to the internal side of the anonymous method.
2. Insecure code cannot be accessed within an anonymous method. In addition, you cannot access the ref and out parameters defined outside the anonymous method. However, other variables defined outside the anonymous method can be used.
Public Delegate void print (); // defines a delegate Public Delegate int getlength (string Str ); // define a delegate class program {static void main (string [] ARGs ){PrintP = delegate // The anonymous method without parameters {console. writeline ("are you good at home? ") ;}; P (); getlength G = delegate (string Str) // an anonymous method with parameters. Note that the parameters of the method must be consistent with those of the delegate {return Str. length ;}; int length = g ("are you okay? "); // Call the delegate. Be sure to pass in the console. writeline (length); console. readkey () ;}} parameter ();}}
VII. Lambda expressions
Lambda expressions and anonymous methods are basically the same, but their syntax is different. It can be said that Lambda expressions are anonymous methods. It must be remembered that Lambda is an anonymous method, which is used to assign values to the delegate. That is to say, in Lambda scenarios, only the delegate is assigned a value.
The syntax of lambda expressions is more concise:
(PARAM) => expr// Param is an output parameter list. To put it bluntly, it is a delegate parameter. expr is an expression or a series of statements. To put it bluntly, it is an output or executed operation.
Lambda expressions have the following features:
1. In a Lambda expression with a unique explicit parameter, parentheses can be deleted from the parameter list. Example: Param => expr
2. When the input parameters are not unique, brackets cannot be omitted.
3. Each parameter in the input parameter list can explicitly specify the type or omit the parameter type. The specific type is determined by the type inference mechanism.
4. expr can contain only one computing expression or a series of statements, except that a series of statements must be included in braces.
Lambda expression of a delegate parameter
Public Delegate string print (string content); // defines a delegate that receives a string input for the class program {static void main (string [] ARGs on the left of Lambda) {print P = (STR) => STR + = "-output parameter"; // (STR) the input parameter, that is, the content in the delegate parameter. The Arrow is the output, the simplest understanding is that the left side of the arrow is the input, and the left side of the arrow is the output. Of course, the statements are different. String outstr = P ("input parameter"); console. writeline (outstr); // output input parameter-output parameter console. readkey ();}}
Call of lambda expressions for two delegate parameters:
Public Delegate string print (string content1, string content2); // defines a delegate class program {static void main (string [] ARGs) {print P = (str1, str2) => str1 + = "left-right" + str2; // multiple input parameters. The string outstr = P ("Zhang Fei", "Guan Yu") cannot be omitted in parentheses "); // output Guan Yu, left-right, Zhang FeiConsole. Writeline (outstr); // output input parameter-output parameter console. readkey ();}}
Lambda expressions with statements
Public Delegate void print (string content); // defines a delegate class program {static void main (string [] ARGs) {print P = STR => // a Lambda expression with a statement. Since there is only one parameter, parentheses can be omitted {Console. Writeline (STR) ;}; P ("hello"); // helloConsole. Readkey ();}}
2014-04-08 -----------------------------
Now that I have learned the lambda expression, I can use the extension method to see how to implement the function. The following is an example of the where implementation that imitates LINQ:
Namespace consoleapplication3 {Public Delegate bool compare (int I );Class program {static void main (string [] ARGs) {//. Net's LINQ extension is ienumerable <tsource> (bottom layer, wide range), and I'm a calculate classCalculateC = newCalculate(); Int [] intarr = new int [] {10, 20}; int [] intarrreturn = C. Where (M => m> 18, Intarr); foreach (int I in intarrreturn ){Console. Writeline (I );}Console. Readkey () ;}} public static classExten{// Technical point 1: The extension method, which extends the calculate class (the first parameter) // technical point 2: The delegate is used as the parameter, the public static int [] will be called inside the method (the second parameter).Where(ThisCalculateC,CompareCompare, int [] intarr) {int [] returnarr = new int [2]; // example of a fixed length array int COUNT = 0; foreach (int I in intarr) {If (Compare (I)) {Returnarr [count] = I; count ++ ;}} return returnarr ;}// calculation class public classCalculate{}}
As a result, the name of LINQ is generic + lambda, so it is handsome. If we change the delegate (parameter name) to: Compare to func <t>
public delegate bool Func<T>(int i);
Check the code prompts. Is it more like LINQ?
Sorry, so far, the extended calculate class does not support chained operations because the returned result is an int [] array. The chain operation principle is that the returned results can continue, for example, the where (M => M. XX) then the returned result is ienumerable <int>, so it can be infinite.
2014-04-08 -----------------------------------
VIII. Coordination and inverter in Delegation
Covariant: the return value type of the delegate method directly or indirectly inherits the return value type of the delegate signature, which is called covariant.
Inverter: The parameter type in the delegate signature inherits from the parameter type of the delegate method, which is called inverter.
Note: The covariant emphasizes the return type, while the inverter emphasizes the method parameters.
Demo of covariant:
Delegate people getson (string name); Class program {static void main (string [] ARGs ){GetsonG = sons;PeopleP = g ("Zhang Fei"); // note that although the delegate method returns son, the delegate itself returns the parent class people console. writeline (P. name); // output Zhang Fei console. readkey ();} public static son sons (string name) // the return value type of the delegate method inherits from the return value type of the delegate signature. {son M = new son (); M. name = Name; return M ;}} public classPeople{Public people () {} public int ID {Get; set;} public string name {Get; Set ;}} public classSon:People{Public int age {Get; Set ;}}
Inverter Demo:
Delegate string getsonname (son s); Class program {static void main (string [] ARGs) {getsonname G = sons; son s = new son (); S. name = "Guan Yu"; string STR = g (s); console. writeline (STR); // output Guan Yu console. readkey ();} public static string sons (People P) // The parameter type of the delegate signature inherits from the parameter type of the delegate method. This people is the parent class of the delegate signature parameter son {return p. name ;}} public classPeople{Public people () {} public int ID {Get; set;} public string name {Get; Set ;}} public class son: People {public int age {Get; set ;}}