Cainiao journey-Understanding delegation and events, and entrusting cainiao journey
This is the first point of interest to me. I did not know when to take notes and thought it was necessary to sort out my knowledge, some of the points are clearer than those at the time. Here, I first post a blog of Daniel. If you are interested, I can check it out. I have introduced in detail the delegation and events, I read it several times and benefited a lot:
C # Delegate and event (continued)
This example is implemented in VS2013.
Initial Recognition Commission
I may be confused when I just learned about delegation. I don't know what the delegation is, how to use it, and what are the advantages. I will explain it in a simple scenario.
Scenario: Let's assume that someone will return home next time, turn on the lights, the water heater, and the TV.
Let's first define a house:
Public class House {public void OpenLight () {Console. WriteLine ("turn on the light! ");} Public void OpenHeater () {Console. WriteLine (" open the water heater! ");} Public void OpenTV () {Console. WriteLine (" Turn on the TV! ");}}
Pass methods as parameters
Next, we will first use the delegate to perform the operations of turning on the light, turning on the water heater, and turning on the TV. We will first define a delegate with no parameters and no return values (in fact. NET has a built-in Action delegate), in the creation of a method to open the electric appliance:
delegate void OpenMachineHandle(); static void OpenMachine(OpenMachineHandle openHandle) { openHandle(); }
Then we can enable the electrical appliance as follows:
Static void Main (string [] args) {House house = new House (); Console. writeLine ("open the door and go home ...... "); OpenMachine (house. openLight); OpenMachine (house. openHeater); OpenMachine (house. openTV); Console. readLine ();}
We can see that we pass the three instance methods of House as parameters, but some people will say that we can directly call methods for implementation? Do you think there is another OpenMachine method? Now, we assume that you do not use a delegate and can use the OpenMachine method to open the electrical appliance (this kind of requirement may exist. For example, OpenMachine is an interface I released as a third party ), if-else or switch is used for resolution. However, if XD is required and the washing machine is enabled, my interface needs to be changed to meet new requirements and then released, if demand changes, isn't it an end-to-end change?
Here we directly open the electric appliance method as a parameter to use, and then add a new open electrical appliance to break the law, you do not need to modify the OpenMachine unified entrance, just add a line of calls in the main program; this can be used in some scenarios.Reduce the use of if-else or switch statements, decouple the program to a certain extent, so that the program has better scalability..
Bind multiple methods by Delegate
Of course, the delegate can also bind multiple methods (both static methods and instance methods can be used, as long as the parameters and return values are the same as those of the Delegate). We can also modify the above programs as needed, we can ignore the unified entrance of OpenMachine, instantiate a delegate, directly bind the open Electrical Method to the delegate, and then let this instance execute all the bound methods on our behalf, there is another method for instantiation, but + = is to add binding,-= is to remove binding, these are certain.
Static void Main (string [] args) {House house = new House (); Console. writeLine ("open the door and go home ...... "); OpenMachineHandle openHandle = house. openLight; openHandle + = house. openHeater; openHandle + = house. openTV; openHandle (); Console. readLine ();}
From delegate to event
In object orientation, we can encapsulate the delegate instance into a class to facilitate use on the client. Here we create a Person class:
public class Person { public string Name { get; set; } public OpenMachineHandle openMachineHandle; public void OpenMachine() { if (openMachineHandle != null) openMachineHandle(); } }
We can use the delegate as follows:
Static void Main (string [] args) {House house = new House (); Person caster = new Person (); caster. name = "Caster"; caster. openMachineHandle = house. openLight; caster. openMachineHandle + = house. openHeater; caster. openMachineHandle + = house. openTV; Console. writeLine ("{0} open the door and go home ...... ", caster. name); caster. openMachine (); Console. readLine ();}
You may find that there are some problems here. The first binding method of openMachineHandle is the = assignment syntax, and the subsequent method will be changed to the + = registration method, in addition, openMachineHandle is directly used as the delegate variable. However, in object-oriented systems, not all member variables can be published. For common member variables, attribute can be used for encapsulation, but the attribute used by the delegate variable cannot solve the first problem, so we can use the event to encapsulate the delegate. In this way, we can rewrite the Person class:
public class Person { public string Name { get; set; } public event OpenMachineHandle OpenMachine; public void OpenDoor() { OpenMachine(); } }
When declaring an event, a private OpenMachineHandle delegate will be constructed by default (the same private variable will be constructed by default when a Name attribute is declared above). For details, refer to the blog above, I am also working on it. After the rewrite is completed, we will re-use it in the main program:
Static void Main (string [] args) {House house = new House (); Person caster = new Person (); caster. name = "Caster"; caster. openMachine + = house. openLight; caster. openMachine + = house. openHeater; caster. openMachine + = house. openTV; Console. writeLine ("{0} open the door and go home ...... ", caster. name); caster. openDoor (); Console. readLine ();}
Here we can directly use the + = registration method to bind the event to be executed. As I mentioned earlier, the OpenMachineHandle delegate has no parameter and no return value, therefore, OpenMachineHandle can be fully replaced with the Action built-in delegate.
. NET built-in delegation introduces the delegate keyword
Delegate is a common declaration.
Delegate has at least 0 parameters and up to 32 parameters. The return value type can be specified or not.
For example, public delegate int MethodtDelegate (int x, int y); indicates that there are two parameters and int type is returned.
Action
Action is a generic delegate without return values.
Action indicates a delegate with no parameter and no return value.
Action <int, string> indicates that the input parameter int exists, and the string value does not return a delegate.
Action <int, string, bool> indicates that the input parameters int, string, and bool have no return value.
Action <int, int> indicates that four int-type parameters are input and no delegate is returned.
Action has at least 0 parameters, up to 16 parameters, and no return value.
Example:
Public void Test <T> (Action <T> action, T p)
{
Action (p );
}
Func
Func is a generic delegate with a returned value.
Func <int> indicates that there is no parameter, and the return value is the delegate of int.
Func <object, string, int> indicates that the input parameter is an object, and the string return value is an int delegate.
Func <object, string, int> indicates that the input parameter is an object, and the string return value is an int delegate.
Func <T1, T2, T3, int> indicates that the input parameter is T1, T2, and T3 (generic), and the return value is the int delegate.
Func has at least 0 parameters and up to 16 parameters. Return results based on the returned value of the generic type. There must be a return value, not void
Example:
Public int Test <T1, T2> (Func <T1, T2, int> func, T1 a, T2 B)
{
Return func (a, B );
}
Predicate
Predicate is a generic delegate that returns the bool type.
Predicate <int> indicates that the input parameter is int and the bool delegate is returned.
Predicate has only one parameter, and the return value is fixed to bool.
Example: public delegate bool Predicate <T> (T obj)
Summary
My delegated learning summary is now over. There are not many things, and further code implementation and design ideas are to be learned, I hope it will be helpful to those who are not familiar with delegation!