The Action and Func

The same

  1. Is the delegate
  2. These are generic delegates
  3. Both have a maximum of 16 parameters

The difference between

  1. Action has no return value and Func has a return value

There’s also a system-defined Predicate, which, less often, only takes one parameter and returns a value of type bool

Actions and Func are system-defined delegates, and we can define them ourselves, but it would be too cumbersome to define them every time we use them

Action

There is no return value

Action<int, int> action = new Action<int, int>(Add);
Copy the code

Defines an Action method that takes two int arguments

private static void Add(int a, int b)
{
    Console.WriteLine("{0} + {1} = {2}", a, b, a + b);
}
Copy the code

Func

There is a return value

Func<int, int, int> func = new Func<int, int, int>(Add2);
Copy the code

The first two ints correspond to a and b of the Add2 method arguments, and the third int is the return value

private static int Add2(int a, int b)
{
    return a + b;
}
Copy the code

Predicate

Pass a parameter and return a bool

Predicate<bool> predicate = new Predicate<bool>(isEqual);
Copy the code

private static bool isEqual(bool b)
{
    return b;
}
Copy the code

Associative Lambda expression

Action

Action<int, int> action = (a, b) => { Console.WriteLine("{0} + {1} = {2}", a, b, a + b); };
Copy the code

When a block of statements has only one statement, it can be further abbreviated as

 Action<int, int> action = (a, b) => Console.WriteLine("{0} + {1} = {2}", a, b, a + b);
Copy the code

Func

Func<int, int, int> func = (a, b) => { return a + b; };
Copy the code

Further shorthand

Func<int, int, int> func = (a, b) => a + b;
Copy the code

Predicate

Predicate<bool> predicate = (b) => { return b; };
Copy the code

Further shorthand

Predicate<bool> predicate = (b) => b;
Copy the code

Used as an argument to a method

Usually methods take common data types, such as int, string, bool, etc

If we want to take a block as an argument, using a plain data type as an argument is not going to work, so we can use delegates instead

A simple example

Defines a method for adding two numbers, but both numbers are obtained using different operations

private static int Add(Func<int> reslut1, Func<int> reslut2)
{
    int num1 = reslut1();

    int num2 = reslut2();

    int sum = num1 + num2;

    return sum;
}
Copy the code

using

This is probably a more complicated process

int a = 2, b = 3;

Add(() =>
{
    int sub = a - b;
    return sub;
}, () =>
{
    int nul = a * b;
    return nul;
});
Copy the code

This might not be a very graphic example, but let’s do a more practical example

A more complicated example

For example, now the implementation of an instruction method, that is, the upper computer software to send instructions to the lower computer, because often send instructions, so the execution of the instruction method is written as a template method

The process of giving instructions; Obtain instructions from the database 2. Assign values to the parameters of instructions 3. Execute instructions (which are divided into sending and waiting results) 4. Parses the results of executing instructions

Now, use a simple example to simulate the process of issuing instructions

First build two models, one store instruction, one store instruction running results

/// </summary> public class Instruction {/// </summary> // Name // </summary> public string Name; // </summary> // </summary> public int CurNo; /// <summary> // parameter /// </summary> public byte[] Param; } /// <summary> /// instruction execution details /// </summary> public class OperateDetail {/// <summary> /// parameters /// </summary> public byte[] Param; }Copy the code

Template methods for executing instructions

public static bool ExecuteTemplet(Func<Instruction> Ins, out OperateDetail reslut) { reslut = new OperateDetail(); Instruction model = Ins(); // Execute instruction (omitted) send instruction model to the lower machine // return result (omitted) assign reslut return true from the query result in the database; }Copy the code

Now that I’ve written the template method,

Now we need to get the set sequence number, write a method to set the sequence number,

The template method is called so that the method that executes the instruction and returns the result is not repeatedly written

public static bool SetSN(string sn) { sn = string.Empty; bool bExecute = ExecuteTemplet(() => { Instruction ins = new Instruction(); / / from the database access instructions (omitted) / / assignment of order parameter ins. Param = Encoding. The Default. The GetBytes (sn); ins.CurNo = 1; return ins; }, out OperateDetail reslut); if (bExecute == false) { return false; } return true; }Copy the code

Now there’s a way to get the serial number

public static bool GetSN(out string sn) { sn = string.Empty; bool bExecute = ExecuteTemplet(() => { Instruction ins = new Instruction(); Ins.curno = 1; ins.curno = 1; return ins; }, out OperateDetail reslut); if (bExecute == false) { return false; Analytical results of sn} / / = Encoding. The Default. Get string (reslut. Param); return true; }Copy the code

From these two methods, we can see that using Func as a method parameter, you can define template methods, do not have to repeat the same code, post-maintenance is also simple