First, the reference method
The delegate is the addressing method. NET version. A delegate is a type-safe class that defines the type of the return type and the parameter. A delegate is a reference to a method, or multiple methods can be referenced, and a delegate can be understood as a pointer to a method address.
such as: Delegate int returninthandler (int a,int b),//int is the return type, A and B are reference types, and this is the method that the delegate executes must meet the following format: Int method (int param1,int param2);
Second, the Commission
You need to use a delegate when you want to pass the method to another method. A delegate is a special type of object, except that all objects that we have previously defined contain data, and the delegate contains only the address of one or more methods.
1. Declaration of Entrustment
The delegate is defined using the keyword delegate.
Defining a delegate is basically defining a new class, so you can define a delegate anywhere in the definition class. You can apply common access modifiers on a delegate definition: public, private, protected, and so on. Its access scopes are similar to classes.
2. Use the delegate
To reduce the amount of input, only the delegate instance is required to pass the name of the address. This is called delegate inference.
Delegate intCalculatemethodinvoker (intXinty); classProgram {Static voidMain (string[] args) {Calculatemethodinvoker Calculatemethodinvoker=calculatehelper.sum; intx = -, y = $; Console.WriteLine ("x, y add: {0}", Calculate (Calculatemethodinvoker, x, y)); Calculatemethodinvoker=calculatehelper.multiply; Console.WriteLine ("x, y multiplication: {0}", Calculate (Calculatemethodinvoker, x, y)); Console.readkey (); } Public Static intCalculate (Calculatemethodinvoker Calculatemethodinvoker,intXinty) {//return Calculatemethodinvoker (x, y); //return Calculatemethodinvoker.invoke (x, y);//whether the current thread is availableIAsyncResult result = Calculatemethodinvoker.begininvoke (x, Y,NULL, Calculatemethodinvoker);//Async, this is just a show, EndInvoke is similar to an await in async, where asynchronous effects cannot be implemented returnCalculatemethodinvoker.endinvoke (Result); } } Public classCalculatehelper { Public Static intSum (intXinty) {returnX +y; } Public Static intMultiply (intXinty) {returnX *y; } }
3, action<t> and Func<t> commissioned
In addition to defining a new delegate type for each parameter and return type, you can also use action<t> and func<t> delegates.
A generic action<t> delegate represents a method that references a void return type, and an action class that does not have a generic parameter can invoke a method with no arguments, such as an action equivalent to delegate void MyDelegate; Action<int,int> equivalent to delegate void mydelegate (int param1,int param2);
The generic func<t> delegate refers to a method that has a return value, the last parameter of the generic when the return value type of func, such as Func<int,int,bool>, is equivalent to delegate bool MyDelegate (int Param1,int param2);
4. Multicast delegation
A delegate can also contain multiple methods. This delegate becomes a multicast delegate. If you call a multicast delegate, you can call multiple methods sequentially consecutively. For this reason, the signature of the delegate must return void, otherwise, only the result of the last method invoked by the delegate is obtained. The multicast delegate recognizes the operator "-", "+", "-=", "+ =" to add or remove method calls from the delegate.
Such as:
classProgram {Static voidMain (string[] args) {Action<int,int> Calfunc =calculatehelper.sum; Calfunc+ = calculatehelper.multiply;//Multicast plus intx = -, y = $; Calculate (Calfunc, x, y); Calfunc=calfunc-calculatehelper.multiply;//Multicast ReductionCalculate (Calfunc, x, y); Console.readkey (); } Public Static voidCalculate (action<int,int> Calculatemethodinvoker,intXinty) {Console.WriteLine ("Operation Result:"); //calculatemethodinvoker (x, y); foreach(action<int,int> IteminchCalculatemethodinvoker.getinvocationlist ())//traversal, where you need to switch to the current type delegate { Try{item (x, y);//executing a delegate-pointing method } Catch(Exception ex) {Console.WriteLine (ex). Message); } } } }
If an exception is thrown by one of the methods called by the delegate, the entire iteration is stopped. The workaround is to get an array of delegate objects using the Getinvocationlist () method defined in the delegate class, and then use the loop traversal execution to catch the exception in the process to continue the next iteration.
5. Anonymous method
An anonymous method is a piece of code that acts as a parameter to a delegate.
Such as:
Action<int, int> calfunc = delegate (int i, int j) { Console.WriteLine ("X, y add: {0}", i + j);};
You cannot use a jump statement (break, Goto, or Continue) in an anonymous method, you cannot access unsafe code inside an anonymous method, and you cannot access the ref and out parameters that are used outside of an anonymous method.
Third, lambda expression
After c#3.0, you can use lambda to assign the implementation code to a delegate, and you can use a lambda expression wherever there is a delegate parameter type.
Such as:
Action<int, int> Calfunc = (i, j) =>{ Console.WriteLine ("X, y add: {0}", i + j);};
1. Parameters
Lambda expressions have several ways to define parameters. If there is only one argument, it is sufficient to write only the parameter name. In addition to a parameter, parentheses are required to enclose the name of the parameter.
Example:
action<int> one = i =>{ //method body}; Action<int, int> II = (i, j) =>{ //method Body};
2, multiple lines of code
If the lambda represents only one statement, no curly braces and return statements are required within the method block because the compiler implicitly adds a return.
Such as:
Func<int> Lambdaone = () = 0;
If the implementation code is more than one line, you need to return it explicitly using the return statement.
Such as:
func<int> Lambdaone = () =
{ int i = 0; i++; ++i; return i;};
3. Closed Package
A lambda expression provides access to variables outside the lambda expression block. This is called closures.
Such as:
int param = 10; Action<int> Lambdasecond = (i) =>{ Console.WriteLine (i + param);}; Lambdasecond (3); Console.readkey ();
Iv. Events
Events are based on delegates and provide a publish/subscribe mechanism for delegates.
Such as:
classProgram {Static voidMain (string[] args) {AlarmClock AlarmClock=NewAlarmClock (); Student zsstudent=NewStudent ("Zhang San"); Alarmclock.itsgetupclockevent+=Zsstudent.itsgetupclock; Alarmclock.itsgetupclock (); Student lsstudent=NewStudent ("John Doe"); //Weakeventmanager<alarmclock, Eventargs> AddHandler (AlarmClock, "itsgetupclockevent", lsstudent.itsgetupclock); ////weak events, often used in SYSTEM.WINDOWS,WPF //Alarmclock.itsgetupclock ();Console.readkey (); } } //Event Publishing Class Public classAlarmClock { Public EventEventhandler<eventargs>itsgetupclockevent; Public voidItsgetupclock () {Console.WriteLine ("It 's time to get up! "); Itsgetupclockevent?. Invoke ( This,NewEventArgs ());//deciding whether to subscribe to an event } } //Event Listener Class Public classStudent { Public stringName {Get;Set; } PublicStudent (stringname) { This. Name =name; } Public voidItsgetupclock (Objectsender, EventArgs e) {Console.WriteLine ("{0} Turn off the alarm and get up. ", Name); } }
The most common areas of events are WinForm and WPF forms, while the classic usage scenario for Invoke is as follows (non-current thread changes form text):
Private voidShowexeclog (stringlog) { if( This. richtextbox1.invokerequired)//determines whether the current thread { This. Richtextbox1.invoke (NewShowloghandler (showlog), log); } Else { This. richTextBox1.Text + =log; } } Public voidShowlog (stringlog) { This. richTextBox1.Text + =log; } Public Delegate voidShowloghandler (stringLOG);
C # Delegate Knowledge