Some personal understanding of delegation, anonymous functions, Lambda expressions in C #

0x01 defines a delegate, which is equivalent to defining a special variable type that can store a method

Below we look at the specific code, through the code to better understand

delegate void IntMethodInvoker(int x);

This line of code is to declare a delegate, which delegateis a keyword, which means to declare a delegate, voidis the return type of the method to be stored, IntMethodInvokeris the name of the delegate type declared, combined with the first sentence is the custom class book variable type name, int xIs the return type of the method to be stored


What methods can such a delegate store?

As long as the return type is the same , methods with the same parameter list can be stored

In this example, the return type is void and there is a method of int parameter

void test(int t)
{
    Console.WriteLine("Just a test" + t )
}

Such a test method can be stored in the IntMethodInvokerdelegated instance

The delegate is a special type of object, after defining the delegate, you can create an instance of it and then store the method

IntMethodInvoker DelegateTest = test;

This line of code will store the address of the test method in the IntMethodInvokerdelegated instance DelegateTest, and the DelegateTesttest method can be executed only by calling it in the future .

DelegateTest(32);

This line of code test(32)has the same effect


Delegates can add multiple method references , and delegates that add multiple method references are called multicast delegates

Add multiple method references using + =, to delete added method references use-=

0x02 Use delegates to pass methods as parameters

Since we said earlier that delegation is similar to defining a special variable type that can store a method, then we can also use this special type as a formal parameter of a method, add a method reference to the delegate instance, and then use the delegate instance as another accept delegate The actual parameter of the method of type parameter, to achieve the effect of passing the method to another method

class Program
{

    static void Main(string[] args)
    {
        Test test = new Test();
        Test.TestDelegate testDelegate = new Test.TestDelegate(test.Fun);

        test.KK(testDelegate);
    }
}
class Test
{
    public delegate void TestDelegate();

    public void Fun()
    {
        Console.WriteLine("这是一个简单的方法!");
    }
    public void KK(TestDelegate testDelegate)
    {
        Console.WriteLine("这是一个接收委托的方法");
        testDelegate();
    }
}

This is an example of passing a method as a parameter to another method

In this example, first declare a Test instance, then declare a TestDelegatedelegate instancetestDelegate

testDelegatetest.Fun()The reference contained in the delegate is not called at this time test.Fun(), but the reference is saved

Next execution test.KK(testDelegate), when the testDelegatedelegate is passed to the KK method as a formal parameter

When the KK method is called testDelegate();, delegate the Fun method

So the final execution result is

This is a method of receiving a delegate.
This is a simple method!

0x03 Func<T>andAction<T>

Delegates are very common, so .Net has two types of delegates built in, so that we do n’t have to declare the delegate ourselves

Action<T>Generic delegate means to refer to a method of void return type. There are different variants of this delegate, and methods that require 0 to 16 parameters can be accepted

Func<T>Generic delegates are Action<T>similar to but refer to a method that has a return value type. Func<T>The method can also receive 0 ~ 16 parameters, the default last one is the return type, that is, Fun<T>up to seventeen parameters

Func<string,string,int>

This Func indicates that it can receive a parameter list as two strings and return an int method.

0x03Lambda and anonymous methods

Anonymous method:

Func<string, string> anonDel = delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

The role of anonymous methods:

Delegates are references to stored methods, that is to say, to use a delegate, you must first have a method, but in fact there are many times the method reference stored in the delegate will only be used in the delegate or event (event based on the delegate), this time It is very troublesome to define a method separately. At this time, you can use the anonymous method. The above is an anonymous method. Let ’s look at the right

delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

This is an anonymous method, using delegatekeywords, if we delegatereplace it with a common name

KK (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

This is a common method (the semicolon at the end is the end of the Fun delegate assignment statement), so the anonymous method is a common method to remove the method name and replace it with a delegate to simplify the code

Func<string, string> anonDel = 

delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
};

Is it easy to understand?

Lambda expression:

In my understanding, Lambda expressions are actually to simplify anonymous methods

We still use the above code

//匿名方法
delegate (string param)
{
    param += mid;
    param += " and this was added to the string.";
    return param;
}


//Lambda表达式
(string pram) =>
{
    param += mid;
    param += " and this was added to the string.";
    return param;
}

These two are equivalent versions. => Is the Lambda operator. Now let's see what the two sides are, the parameter list on the left, and the method body on the right.

This Lambda is actually a bit more complicated, usually we encounter Lambda will be more simplified

  • If there is only one parameter, only the parameter name is enough, that is, in this Lambda, (string pram) can be rewritten as pram
  • If the method body has only one line of statements, then no braces and return statements are needed in the method block

for example

Func<double,double> square = (double x) =>
{
    return x*x;
};

This Lambda expression can be abbreviated as

Func<double,double> square = x => x*x

Lambda expression closure problem

Here is a sentence, in the Lambda expression uses an external variable (not the variable in the Lambda expression), the value of the external variable is determined at the time of the call, not when the Lambda expression is defined

int someVal = 5;
Func<int, int> ZZ = x => x + someVal;
someVal = 7;
Console.WriteLine(ZZ(3));

The last output is 7, because someVal is already equal to 7 when the ZZ delegate calls the Lambda expression

Guess you like

Origin www.cnblogs.com/wujuncheng/p/12700157.html