First, what is a delegatePrincipal-based expansion:http://www.cnblogs.com/yangyancheng/archive/2011/04/21/2024145.html1.1 official explanation
A delegate is a type that defines a method signature. When you instantiate a delegate, you can associate its instance with any method that has a compatible signature. You can invoke a method from a delegate instance.
1.2 People understand
A delegate is a class that executes a method (function).
An event is a special kind of delegate.
Second, how to affirm the entrusted 2.1 delegate
public delegate int Testdelegate (int x, int y);
2.2 Action
Action is a generic delegate with no return value.
The Action represents a delegate without parameters and no return value
Action<int,string> represents a delegate with an incoming parameter int,string no return value
2.3 Func
Func is a generic delegate with a return value
Func<int> represents no parameter and returns a delegate with a value of int
Func<object,string,int> indicates that an incoming parameter is an object, and a string returns a delegate with a value of int
2.4 Predicate
predicate is a generic delegate that returns a bool type
Predicate<int> represents a delegate that returns a bool to an int with an argument.
2.5 The difference between four people
Delegate at least 0 parameters, up to 32 parameters, can have no return value, or you can specify a return value type
Action at least 1 parameters, up to 4 parameters, no return value,
Func at least 0 parameters, up to 4 parameters, are returned based on the return value generic. Must have a return value, not void
predicate at least 1 parameters, up to 1 parameters, return value fixed to bool
Iii. How to use the delegate 3.1 LABMDA expression
Testdelegate d2= (string name) = {Console.WriteLine ("Hello, {0}! ", name);};
D2 ("Terry");
3.2 Anonymous Methods
delegate void Testdelegate (string myName);
Testdelegate D2 = Delegate (string name)
{
Console.WriteLine ("Hello,{0}! ", name);
};
D2 ("Test");
3.3 Function Declaration
private void Delegatemethod (string name)
{
Console.WriteLine ("Hello,{0}! ", name);
}
Testdelegate D2 = new Testdelegate (Delegatemethod);
D2 ("Test");
Iv. What are the characteristics of using a delegate?
Delegates are similar to C + + function pointers, but they are type-safe.
A delegate allows a method to be passed as a parameter.
Delegates can be used to define callback methods.
Delegates can be chained together; For example, multiple methods can be called on an event.
method does not have to match the delegate signature exactly.
V. Delegate usage Scenarios
Delegates are generally used in observer mode (Observer mode).
The observer design pattern is to define a one-to-many dependency between objects, so that when an object's state changes, other objects that depend on it are automatically notified and updated.
The observer model consists of the following two types of objects:
Monitored objects: often contain content that other objects are interested in.
Monitor: When something happens in an object, the builder is told, and the builders take action accordingly.
For example, when you process a large amount of data, you need to display the progress bar in the program interface friendly hints, then you through the delegation to achieve quite convenient.
Example:
public delegate void Delegatemethod (int position, int maxValue);
public class Testdelegate
{
Public Delegatemethod ondelegate;
public void Dodelegatemethod ()
{
int maxValue = 100;
for (int i = 0; i < MaxValue; i++)
{
if (this. Ondelegate = null)
{
This. Ondelegate (i, maxValue);
}
}
}
}
Testdelegate test = new Testdelegate ();
This.textBox1.Text = "";
This.progressBar1.Value = 0;
Test. Ondelegate = new Delegatemethod (delegate (int i, int maxValue)
{
This.textBox1.Text + = i.tostring () + Environment.NewLine;
This.progressBar1.Maximum = MaxValue;
this.progressbar1.value++;
});
Test. Dodelegatemethod ();
Vi. How to empty a delegate
1. Declare the empty delegate method in the class, and loop to remove the delegate reference in turn.
Here's how:
public class Testdelegate
{
Public Delegatemethod ondelegate;
public void Cleardelegate ()
{
while (this. Ondelegate = null)
{
This. Ondelegate-= this. Ondelegate;
}
}
}
2. If the method of emptying the delegate is not declared in the class, we can use Getinvocationlist to query the delegate reference and then remove it.
Here's how:
Testdelegate test = new Testdelegate ();
if (test. Ondelegate = null)
{
system.delegate[] dels = test. Ondelegate.getinvocationlist ();
for (int i = 0; i < dels. Length; i++)
{
Test. Ondelegate-= dels[i] as Delegatemethod;
}
}
Vii. Examples of actual combat
Functional Requirements: Query the print machine toner amount, if less than 50 send email to the customer to remind.
Pre-optimization Code
Namespace Delegateexample.before
{
public class Spyprintertoner
{
public void Checkprintertonerislower ()
{
Physicalprinteraction action = new physicalprinteraction ();
int remaintoner = action. Selectprintertoner ();
if (Remaintoner < 50)
{
Messagecontroller controller = new Messagecontroller ();
Controller. SendMessage ("Printer Name");
}
}
}
public class Messagecontroller
{
public void SendMessage (string printername)
{
Todo:sendmessage
}
}
public class Physicalprinteraction
{
public int Selectprintertoner ()
{
return 80;
}
}
}
Call:
DelegateExample.Before.SpyPrinterToner toner = new Before.spyprintertoner ();
Toner. Checkprintertonerislower ();
The above code can be said to use object-oriented programming, but there is an unnecessary coupling between spyprintertoner and Messagecontroller, resulting in the future of the program maintenance workload and inconvenience to the extension of the program.
So how to reduce the coupling between spyprintertoner and Messagecontroller, so as to achieve: cohesion poly, low coupling.
Obviously we can use the observer pattern to achieve.
Optimized code
Namespace Delegateexample.after
{
public class Spyprintertoner
{
Public action<string> Onsendmessage;
public void Checkprintertonerislower ()
{
Physicalprinteraction action = new physicalprinteraction ();
int remaintoner = action. Selectprintertoner ();
if (Remaintoner < 50)
{
if (this. Onsendmessage = null)
{
This. Onsendmessage ("Printer Name");
}
}
}
}
public class Messagecontroller
{
public void SendMessage (string printername)
{
Todo:sendmessage
}
}
public class Physicalprinteraction
{
public int Selectprintertoner ()
{
return 80;
}
}
}
Call
DelegateExample.After.SpyPrinterToner toner = new After.spyprintertoner ();
Toner. Onsendmessage + = new Action<string> (new After.messagecontroller (). SendMessage);
Toner. Checkprintertonerislower ();
With this optimization, the direct coupling of the 2 classes is reduced.
If the requirements change in the future, you need to increase the IM type of messages or other types of message categories, then we only need to add another delegate, if not by the implementation of the delegate, the Spyprintertoner class and IM processing classes or other classes are coupled with each other.
Viii. using Func to delegate code optimization
Similar code is often seen during the development of a project:
Try
{
Do ();
}
catch (Exception ex)
{
Logexception (ex);
}
Finally
{
Dofinally ();
}
The redundancy of the code amount will cause a lot of inconvenience to the maintenance of code in the future.
There are many ways to do this, such as: AOP, delegation, and so on. Here we mainly talk about how to use the Func delegate to achieve code optimization.
private void Callmethod (func<string> Func)
{
Try
{
Func ();
}
catch (Exception ex)
{
Logexception (ex);
}
Finally
{
Dofinally ();
}
}
Callmethod (New func<string> (do));
We passed the method as a delegate, which saved a lot of redundant code.
C # Delegate Application summary