C# delegates and events, anonymous functions and lamabda expressions

Article directory

  • (1) commission
  • (2) Events
  • (3) Anonymous function
  • (4) lambda expression
  • (5) Closure

(1) Delegation

The delegate is the container of the function method, which can be understood as the variable type of the function method, which is used to store the transfer function method

The essence of delegation is a class, which is used to define the type of function method (type of return value and parameter)

keyword delegate

using System;
namespace Test
{<!-- -->
// delegate
    //Access modifier delegate return value delegate name (parameter list);
    //Write more into the namespace, and can also be written into the class
    delegate void MyFun();//Function container with no parameters and no return value
    // public when the access modifier is not written
    public delegate int MyFun1(int a);// cannot duplicate the name and cannot overload
class Program
{<!-- -->
public static void Main(string[] args)
{<!-- -->
// no parameters
\t\t\t//method one
            MyFun f1 = new MyFun(Fun);//The parameter is the function method name that meets the conditions
            Console.WriteLine("-method 1-");
            f1.Invoke();//Call the function in the delegate
            //Method 2
            Console.WriteLine("-method 2-");
            MyFun f2 = Fun;//without parentheses
            f2();
            //contains parameters
            Console.WriteLine("-method 1-");
            MyFun1 f3 = new MyFun1(Fun2);
            Console.WriteLine(f3.Invoke(1));
            Console.WriteLine("-method 2-");
            MyFun1 f4 = Fun2;
            Console. WriteLine(f4(1));
            //multicast
            Console.WriteLine("--multicast delegation--");
            MyFun ff = new MyFun(Fun);
            ff + = Fun1;//Delegate variables store multiple functions and execute them in the order they are added
            ff.Invoke();
            //Remove the specified function
            ff -= Fun1;
            // clear function
            ff = null;
            //Use the commission that comes with the system, you must refer to the using System namespace when using it
            Console.WriteLine("--system delegate Action--");//Action delegate without return value
            Action action = null;//Action delegate no parameter delegate
            action + = Fun1;
            action. Invoke();
            Action<string,int> action2 = null;//Action generic n parameter delegation (n<=16)
            action2 + = Fun4;
            action2.Invoke("nihao",123);
            Console.WriteLine("--system delegation Func--");//Func generic has a return value delegation
            Func<string> func = null;//Func generic no parameter sting return value delegate
            func += Fun3;
            Console. WriteLine(func. Invoke());
            Func<int,int> func2 = null;//Func generic front parameter, last return value
            func2 + = Fun2;
            func2.Invoke(16);
}
static public void Fun()
{<!-- -->
Console.WriteLine("void Fun");
}
static public void Fun1()
{<!-- -->
Console.WriteLine("void Fun1");
}
static public int Fun2(int value)
{<!-- -->
Console.Write("int Fun2:{0}",value);
return value;
}
static public string Fun3()
{<!-- -->
return "string Fun3";
}
static public void Fun4(string s,int i)
{<!-- -->
Console.WriteLine("void Fun4 string:{0},int:{1}",s,i);
}
}
class Test // can be delegated in the class
{<!-- -->
public MyFun fun1;
public MyFun1 fun2;
public void AddMyFun(MyFun fun1,MyFun1 fun2)
{<!-- -->
this. fun1 + = fun1;
this. fun2 + = fun2;
}
public void RemoveMyFun(MyFun fun1, MyFun1 fun2)
{<!-- -->
this. fun1 -= fun1;
this. fun2 -= fun2;
}
}
}

(2) Event

An event is a special kind of delegation, and an event is a security package of a delegation, which makes the use of the delegation more secure

using System;
namespace Test
{<!-- -->
//Access modifier event delegate type event name;
//Can only exist as a member variable in classes, interfaces and structures are the same as delegate usage
//Compared to delegated events, they cannot be assigned and called outside the class
class test
{<!-- -->
//Delegate member variables for storing functions
public Action myFun;
//Event member variables are used to store functions
public event Action myEvent;
public Test()
{<!-- -->
myFun = TestFun;
myFun += TestFun;
myFun -= TestFun;
myFun();
myFun. Invoke();
myFun = null;
myEvent = TestFun;
myEvent += TestFun;
myEvent -= TestFun;
myEvent();
myEvent.Invoke();
myEvent = null;
}
public void TestFun()
{<!-- -->
Console.WriteLine("NoProblem");
}
}
class Program
{<!-- -->
public static void Main(string[] args)
{<!-- -->
Test test = new Test();
//The delegate can be assigned externally
test.myFun = null;
test.myFun = TestFun;
//Events cannot be assigned externally
//test.myEvent =null;//report an error
//test.myEvent =TestFun;//report error
//A function that cannot be assigned but can add or remove records by adding or subtracting
test.myEvent += TestFun;
//The delegate can be called externally
test. myFun();
test.myFun.Invoke();
//Events are not allowed;
//test.myEvent();//report error
//test.myEvent.Invoke();//report an error
}
static public void TestFun()
{<!-- -->
Console.WriteLine("MainFunNoProblem");
}
}
}
  • why is there an event

Prevent external random empty delegation

Prevent external random calls to delegates

  • the difference

The event can no longer use the assignment = symbol externally, only + - delegate can be used anywhere.

Events cannot be executed externally, and delegates can be executed anywhere.

Events cannot be used as temporary variables in functions Delegates can.

(3) Anonymous function

A function without a name, mainly used in conjunction with events and delegates

using System;
namespace Test
{<!-- -->
class Program
{<!-- -->
public static void Main(string[] args)
{<!-- -->
// Declare an anonymous function
// no parameter no return
Action a1 = delegate()
{<!-- -->
Console.WriteLine("Anonymous function with no parameter and no return");
};
//The function code will be executed only when the function container is called
a1.Invoke();
//with parameters but without return
Action<int,string> a2 = delegate(int i,string s)
{<!-- -->
Console.WriteLine("Anonymous function with parameters and returns {0}{1}",i,s);
};
a2(520,"Hello");
// return value without parameters
Func<string> f1 = delegate()
{<!-- -->
return "Anonymous function with return value and no parameters";
};
Console. WriteLine(f1. Invoke());
//There is a return value and parameters
Func<string,string> f2 = delegate(string s)
{<!-- -->
return s;
};
Console.WriteLine("Anonymous function with return value and parameters" + f2.Invoke("I'm good"));
//Often used when passing in parameters
Test t = new Test();
t.doSomething("Hello",delegate(){<!-- -->Console.WriteLine("Anonymous function passed in with parameters");});
t.doSomething("The anonymous function passed in with the parameter is a1", a1);
//You can also write anonymous functions in parts
Action ac = t. GetFun();
ac();
\t\t\t
t.GetFun()();//Equal to the above code, one-step call
// Disadvantages of anonymous functions
//Do not record and cannot be removed separately
Action a3 = delegate()
{<!-- -->
Console.WriteLine("Anonymous function 1");
};
a3 + = delegate()
{<!-- -->
Console.WriteLine("Anonymous function 2");
};
a3();
//Because the anonymous function has no name, there is no way to specify to remove an anonymous function
a3 -= delegate()//new function, not 1 above
{<!-- -->
Console.WriteLine("Anonymous function 1");
};
a3();
}
}
class test
{<!-- -->
public void doSomething(string s, Action fun)
{<!-- -->
Console.WriteLine("executed a piece of code {0}",s);
fun();
}
public Action GetFun()
{<!-- -->
return delegate()
{<!-- -->
Console.WriteLine("I just want to return a function?");//Return anonymous function
};
}
}
}

(4) lambda expression

Lambda expressions can be understood as shorthand for anonymous functions. Except for the different writing styles, they are used exactly the same as anonymous functions, and they are used in conjunction with delegates or events.

using System;
namespace Test
{<!-- -->
class Program
{<!-- -->
public static void Main(string[] args)
{<!-- -->
//Declare anonymous function delegate(parameter list)
//{<!-- -->
//
//}
Action a1 = delegate()
{<!-- -->
Console.WriteLine("Anonymous function with no parameter and no return");
};
a1();
//lambda function
//(parameter list) =>
//{<!-- -->
//
//}
// no parameter no return value
Action a2 = ()=>{<!-- -->Console.WriteLine("Anonymous function with no parameters and no return");};
a2();
// Contains parameters but no return value
Action<int> a3 = (int value)=>{<!-- -->Console.WriteLine("Anonymous function with parameters and no return {0}",value);};
a3(520);
//When there are parameters, the parameter type of lambda can be omitted
Action<int> a4 = (value)=>{<!-- -->Console.WriteLine("Anonymous function with parameters and no return {0}",value);};//No int written
a4(100);
//No parameter and return value
Func<string> f1 = ()=>{<!-- -->return "I love you";};
Console.WriteLine("Anonymous function {0}", f1());
// with parameters and return value
Func<string,string> f2 = (string name)=>{<!-- -->return name;};
Console.WriteLine("Anonymous function {0}", f2("Zhang San"));
}
}
}

(5) Closure

Inner functions can refer to variables contained in outer functions
Even if execution of the enclosing function has terminated

Note: The value provided by this variable is not the value when the variable is created, but the final value within the scope of the parent function

using System;
namespace Test
{<!-- -->
class test
{<!-- -->
\t\t//Closure
//The inner function can refer to the variable contained in the outer function
//Even if the execution of the outer function has terminated
//Note: The value provided by this variable is not the value when the variable is created, but the final value within the scope of the parent function
public Action action;
public Test()
{<!-- -->
int value = 10;//It turns out that the constructor is destroyed after execution
action = ()=>{<!-- -->Console.WriteLine(value);};//It is equivalent to saving the value of value with action, changing the original life cycle and becoming a closure
for(int i=9;i>0;i--)
{<!-- -->
action + = () =>
{<!-- -->
//Note: The value provided by this variable is not the value when the variable is created, but the final value within the scope of the parent function
Console.WriteLine(i);//Not 987654321, but the final value of i is 0
};
}
for(int i=9;i>0;i--)
{<!-- -->
int index = i;//The index created each time is a new value
action + = () =>
{<!-- -->
Console.WriteLine(index);//987654321
};
}
}
}
class Program
{<!-- -->
public static void Main(string[] args)
{<!-- -->
Test t = new Test();
t. action();
}
}
}

The following content was referred to during the learning process, and I sincerely thank the knowledge sharers!

Microsoft | Microft docs (C# Programming Guide)

Rookie Tutorial | C# Tutorial

Donald Lion | C# Quartet

Suzkfly | C# Random Numbers

Please call me AXin | Sorting Algorithm: Heap Sorting [Illustration + Code]