[Reading Notes] Chapter 8 Delegation, lambda Expressions and Events in C# Advanced Programming

Keywords: C# Lambda

(1) Citation method

Delegates are. NET versions of addressing methods. Delegates are type-safe classes that define the types of return types and parameters. Delegates contain not only references to methods, but also references to multiple methods.

Lambda expressions are directly related to delegates. When parameters are delegate types, lambda expressions can be used to implement delegate reference methods.

 

(2) Entrustment

Delegation is required when passing methods to other methods. A delegate is a special type of object, which is unique in that all the objects we defined previously contain data, while delegates contain only the addresses of one or more methods.

 

1. Declaring Entrustment

Delegate is defined using the keyword delegate.

Example:

Define a delegate named IntMethodInvoker whose return type is void parameter is an int

delegate void IntMethodInvoker(int x);

Because defining delegates is basically defining a new class, delegates can be defined anywhere in the same place as classes. Common access modifiers can be applied to delegate definitions: public, private, protected, etc.

 

2. Use of delegation

 1 delegate int CalculateMethodInvoker(int x, int y);
 2 class Program
 3 {
 4     static void Main(string[] args)
 5     {
 6         CalculateMethodInvoker calculateMethodInvoker = CalculateMethodHelper.Sum;
 7         int x = 100, y = 200;
 8         Console.WriteLine("x,y Add up:{0}", Calculate(calculateMethodInvoker, x, y));
 9         calculateMethodInvoker = CalculateMethodHelper.Multiply;
10         Console.WriteLine("x,y Multiplication:{0}", Calculate(calculateMethodInvoker, x, y));
11         Console.ReadKey();
12     }
13     public static int Calculate(CalculateMethodInvoker calculateMethodInvoker, int x, int y)
14     {
15         return calculateMethodInvoker(x, y);
16     }
17 }
18 public class CalculateMethodHelper
19 {
20     public static int Sum(int x, int y)
21     {
22         return x + y;
23     }
24     public static int Multiply(int x, int y)
25     {
26         return x * y;
27     }
28 }

Running the above code, the results are as follows:

 

To reduce the amount of input, only the delegate instance is needed to pass only the name of the address. This is called delegation inference.

 

3. Action < T > and Func < T > Commissions

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 without generic parameters can call a method without parameters.

Generic Func < T > delegates refer to a method with a return value.

 

4. Multicast Delegation

Delegates can also contain multiple methods. This delegation becomes a multicast delegation. If you call a multicast delegate, you can call multiple methods sequentially. For this reason, the delegated signature must return void; otherwise, only the result of the last method invoked by the delegate can be obtained. Multicast delegate identification operators "-", "+", "-=", "+=" to add or delete method calls from delegates.

Example:

 1 class Program
 2 {
 3     static void Main(string[] args)
 4     {
 5         Action<int, int> calFunc = CalculateMethodHelper.Sum;
 6         calFunc += CalculateMethodHelper.Multiply;
 7         int x = 100, y = 200;
 8         Calculate(calFunc, x, y);
 9         Console.ReadKey();
10     }
11     public static void Calculate(Action<int, int> calculateMethodInvoker, int x, int y)
12     {
13         Console.WriteLine("Operation results:");
14         calculateMethodInvoker(x, y);
15     }
16 }
17 public class CalculateMethodHelper
18 {
19     public static void Sum(int x, int y)
20     {
21         Console.WriteLine("x,y Add up:{0}", x + y);
22     }
23     public static void Multiply(int x, int y)
24     {
25         Console.WriteLine("x,y Multiplication:{0}", x * y);
26     }
27 }

If an exception is thrown through one of the methods called by the delegate, the entire iteration stops. The solution is to use the GetInvocationList() method defined in the Delegate class to get an array of Delegate objects, and then use the loop traversal to execute, catch exceptions in the process, to continue the next iteration.

 

5. Anonymous methods

An anonymous method is a piece of code that is used as a delegate parameter.

Example:

Action<int, int> calFunc = delegate (int i, int j)
{
    Console.WriteLine("x,y Add up:{0}", i + j);
};

Jump statements (break, goto or continue) cannot be used in anonymous methods, insecure code cannot be accessed inside anonymous methods, and ref and out parameters used outside anonymous methods cannot be accessed.

 

 

(3) lambda expression

Since C 3.0, you can use the new syntax to assign the implementation code to the delegate, and lambda expressions can be used whenever there is a delegate parameter type.

Example:

Action<int, int> calFunc = (i, j) =>
{
    Console.WriteLine("x,y Add up:{0}", i + j);
};

 

1. Parameters

lambda expressions have several ways of defining parameters. If there is only one parameter, it is enough to write only the name of the parameter. In addition to one parameter, parentheses are needed to enclose the parameters.

Example:

Action<int> one = i =>
{
    //Method content
};
Action<int, int> two = (i, j) =>
{
    //Method content
};

 

2. Multi-line code

If lambda means that there is only one statement, there is no need for curly brackets and return statements in the method block, because the compiler implicitly adds return.

Example:

Func<int> lambdaOne = () => 0;

If the implementation code exceeds one line, you need to use the return statement to explicitly return.

Example:

Func<int> lambdaOne = () =>
{
    int i = 0;
    i++;
    ++i;
    return i;
};

 

3. Closure

Variables outside the lambda expression block can be accessed through lambda expressions. This is called closure.

Example:

int param = 10;
Action<int> lambdaSecond = (i) =>
{
    Console.WriteLine(i + param);
};
lambdaSecond(3);
Console.ReadKey();

Running the above code, the results are as follows:

 

 

 

(4) Incidents

Events are based on delegation, providing a publish/subscribe mechanism for delegation.

Example:

 1 class Program
 2 {
 3     static void Main(string[] args)
 4     {
 5         AlarmClock alarmClock = new AlarmClock();
 6         Student zsStudent = new Student("Zhang San");
 7         alarmClock.ItsGetUpClockEvent += zsStudent.ItsGetUpClock;
 8         alarmClock.ItsGetUpClock();
 9         Student lsStudent = new Student("Li Si");
10         WeakEventManager<AlarmClock, EventArgs>.AddHandler(alarmClock, "ItsGetUpClockEvent", lsStudent.ItsGetUpClock);//Weak events
11         alarmClock.ItsGetUpClock();
12         Console.ReadKey();
13     }
14 
15 }
16 //Event Publishing Class
17 public class AlarmClock
18 {
19     public event EventHandler<EventArgs> ItsGetUpClockEvent;
20     public void ItsGetUpClock()
21     {
22         Console.WriteLine("Time is up, get up!");
23         ItsGetUpClockEvent?.Invoke(this, new EventArgs());
24     }
25 }
26 //Event listening class
27 public class Student
28 {
29     public string Name { get; set; }
30     public Student(string name)
31     {
32         this.Name = name;
33     }
34     public void ItsGetUpClock(object sender, EventArgs e)
35     {
36         Console.WriteLine("{0}Turn off the alarm clock and get up.",Name);
37     }
38 }

Posted by Zangakat on Sun, 14 Jul 2019 10:21:49 -0700