1, What is delegation?
Delegates are the of addressing methods Net version, in C + +, the function pointer only points to the memory location, which is not type safe. You can't know what this pointer actually points to, nor can you know the parameter type and return type. And Net delegate is a type safe class, which defines the return type and parameter type. From the perspective of IL, it inherits from MulticastDelegate, so delegate is actually a class.
Functionally: delegates are required when methods are passed to other methods as
C#:
IL: the result of IL compilation of the above code shows that it inherits from the parent class MulticastDelegate
2, Delegated usage steps
1. Declaration of entrustment
Defining a delegate is to tell the compiler which type of delegate represents which type of method
//Declare a delegate public delegate void Voiddelegate( int x);// Declare a delegate. The method contained in the delegate takes an int parameter and returns Void public delegate void Void_delegate();//The method contained in the delegate has no parameters and returns Void public delegate int IntDelegate();// The method contained in the delegate has no parameters and returns int public delegate int Int_Delegate(int x);// The method contained in the delegate takes an int parameter and returns Void
Defining a delegate is equivalent to defining a new class, so you can define it anywhere and add any modifiers, public, private
1.1 instantiation delegation
When instantiating, you must pass a method with the same parameters and return values as the delegate
IntDelegate intDelegate = new IntDelegate(test); public static int test(){ return 1; }
1.2 delegate call
intDelegate.Invoke(); intDelegate();//The two are equivalent, and invoke can be omitted //Parameter ①: AsyncCallback is a callback method completed asynchronously. //Parameter ② is a user-defined object, which will be passed to the callback method intDelegate.BeginInvoke(null, null);//Restart a new thread to execute the method intDelegate.EndInvoke(null);//The result of detecting an asynchronous call is usually placed in a callback function
1.3 entrusted usage scenario
It is used to decouple, reduce code instability and reduce duplicate code
public class A{ public delegate void Str_Delegate(string type); public void sayCat(string type){ Console.WriteLine("cat:"+type); } public void sayDog(string type) { Console.WriteLine("Dog:" + type); } public void Say(string type,Str_Delegate str_Delegate){ //You can add common logic here to avoid duplicate code str_Delegate.Invoke(type); } } -------------- static void Main(string[] args) { A a = new A(); a.Say("leslie", new A.Str_Delegate(a.sayCat)); Console.Read(); }
result:
1.4 system built-in delegated Action Func
Action: there is no return value. Parameters are optional. Up to 16 parameters are supported
Func: there must be a return value. Parameters can be optional. Up to 16 parameters are supported. The last parameter is the return value type
public class A { public Action Str_Delegate; public void sayCat() { Console.WriteLine("cat:"); } public void sayDog() { Console.WriteLine("Dog:"); } public void Say() { Console.WriteLine("start say"); Str_Delegate.Invoke(); } } static void Main(string[] args) { A a = new A(); a.Str_Delegate +=a.sayDog; a.Str_Delegate += a.sayCat; a.Say(); Console.Read(); }
1.5 multicast delegation
Any delegate is a multicast delegate because it inherits from the parent class MulticastDelegate
static void Main(string[] args) { inInvoke(null,null); A a = new A(); A.Str_Delegate str_Delegate=a.sayCat; str_Delegate += a.sayDog; str_Delegate.Invoke("leslie"); Console.Read(); }
–
Add and remove a delegate instance through + =, - =. After adding a method, the delegation becomes a method chain, which is executed sequentially
str_Delegate += a.sayDog; //The sayDog method cannot be removed here because it belongs to two different instances str_Delegate -= new A().sayDog;
Note: lamda expressions cannot be removed in multicast delegates
Func delegates can only get the return value of the last method after forming a method chain
2, What is an event
Event is an application scenario of delegation, which is safer than delegation. It can limit permissions and cannot invoke outside the defined class.
1. Declaration event
public class A{ //To declare an Event is to add an Event keyword in front of the delegate declaration public event Action SayHandler; public void sayCat(){ Console.WriteLine("cat:"); } public void sayDog() { Console.WriteLine("Dog:"); } public void Say(){ //Event calls can only be made inside a class SayHandler?.Invoke(); } }
1.1 event call
static void Main(string[] args) { A a = new A(); a.SayHandler += a.sayCat; a.SayHandler += a.sayDog; a.SayHandler.invoke();//An error is reported and cannot be called outside the declared class a.SayHandler = null;//An error is reported and cannot be null outside the declared class; Console.Read(); }
Note: when multicast delegates and events are used, one call can only pass the same parameters to the methods of these delegates. If you want to call each method again and the parameter values are different, you can use the foreach statement to enumerate each call and call the corresponding method separately to pass parameters.
1.3 event usage scenarios
Events are usually used for winform, WPF, encapsulating common logic (mouse over, control color change, etc.)
static void Main(string[] args) { A a = new A(); a.SayHandler += a.sayCat; a.SayHandler += a.sayDog; a.Say(); Console.Read(); } public class A{ public delegate void Str_Delegate(string type); public event Action SayHandler; public void sayCat(){ Console.WriteLine("cat:"); } public void sayDog() { Console.WriteLine("Dog:"); } public void Say(){ Console.WriteLine("start say"); SayHandler?.Invoke(); } }
When the say method is called, the methods registered on the sayhandler event will also be triggered
1.4 events and design patterns
1.3 The code in is actually very much like observer mode and release/subscribe
public event Action sayHanlder is a channel.
a.sayHandler += a.cat is the subscribe r's subscription to the channel.
public void Say() is publisher.
Change the code of 1.3 to observer mode:
public class A{ public List<Action> Actions = new List<Action>(); public void sayCat(){ Console.WriteLine("cat:"); } public void sayDog() { Console.WriteLine("Dog:"); } public void Say(){ Console.WriteLine("start say"); Actions.ForEach(item => { item.Invoke(); }); } static void Main(string[] args) { A a = new A(); a.Actions.Add(a.sayCat); a.Actions.Add(a.sayDog); a.Say(); Console.Read(); }
So there is no difference between the two, just an application in C#.