Bootstrap

委托、Lambda表达式

委托

什么是委托?

委托是类类型,也就是引用类型,能声明变量,创造实例。但委托是一种特殊的类,一般的类是用来反应现实事物的,而委托类只是用来包裹方法的,通过委托实例可以来间接调用这些包裹的方法。所以可以说委托就是一个或一组方法的封装器

using System;
using System.Collections.Generic;
namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //委托能包裹的方法,必须与委托的返回值、参数列表一致。如下就是void返回值、以及0个参数
            MyDele myDele11 = new MyDele(f1);
            myDele11.Invoke();//执行包裹着的方法,可以简化成myDele11();
        }
        static void f1() { Console.WriteLine("方法一"); }
    }
    delegate void MyDele();//委托声明
}


泛型委托

手动声明委托类型

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            MyDele<int> myDele11 = new MyDele<int>(f1);//用int替换T
            myDele11.Invoke(1,2);//执行包裹着的方法

            MyDele<double> myDele22 = new MyDele<double>(f2);//用int替换T
            myDele22(1.21, 3.14159);//执行包裹着的方法
        }
        static int f1(int x,int y) { return x+y; }
        static double f2(double x,double y) { return x+y; }}
    }
    delegate T MyDele<T>(T a,T b);//泛型委托声明
}

实际上类库已经声明好了泛型委托,不用自己去声明。主要有两大类,有返回值的Func,以及无返回值的Action。

以下是使用action委托

using System;
using System.Runtime.CompilerServices;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Action action11 = new Action(f11);//使用action委托封装无参方法
            Action<int, string> action22 = new Action<int, string>(f22);//使用action委托封装有参方法
        }
        static void f11() { Console.WriteLine("我是无参无返回值方法"); }
        static void f22(int a,string s) { Console.WriteLine($"我是#{a}号,{s}"); }
    }
}

以下是使用function委托

using System;
namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var func11 = new Func<int, int, int>(f1);//表示包裹一个为int返回值、2个int参数的方法
        }
        static int f1(int x,int y) { return x+y; }
        static double f2(double x,double y) { return x+y; }}
    }
}

Lambda表达式

lambda 是一种匿名方法、Inline方法(边声明边使用)。

把一个lambda表达式赋值给一个委托类型变量

代码实例:

using System;
namespace ConsoleApp3
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Func<int, int, int> func1 = new Func<int, int, int>((a, b) => { return a + b; });
            Console.WriteLine(func1(231,43));
        }
    }
}

代码详解:

首先里面的lambda表达式是(a, b) => { return a + b; },它处于原本该放方法名的地方,不难相出这个lambda表达式代表着一个方法,表示将int类型的a,b带入花括号中,而花括号代表着返回一个相加后的int值。

观察lambda表达式代表的方法,是匿名的,没有名字。执行到这的时候,是边声明就边使用

这段代码还可以简化成:

 Func<int, int, int> func1 = (a, b) => { return a + b; };

把一个lambda表达式喂给一个委托类型参数

观察上述 Func<int, int, int> func1 = (a, b) => { return a + b; };,它可以将一个lambda表达式来直接实例一个泛型委托,当然具体实现上不是这么简单,但是可以以这种形式完成,那么就可以想到有一个泛型委托形参,我们可以用lambda表达式当成泛型委托实参。

可以用类比int类型,这个泛型委托形参,代表着可以传进去某一组方法(这里是指有2个T参数,1个T返回值),就像int形参,传入参数为像1,3,543这种整数。那个传进去的方法可以用lambda写出表示。

using System;
namespace ConsoleApp4
{
    internal class Program
    {
        static void Main(string[] args)
        {
            FangFa<int>((int a, int b)=>{ return a * b; },100,200);//放入三个参数
        }
        //泛型方法中有3个参数,第一个参数类型是泛型委托
        static void FangFa<T>(Func<T,T,T>func,T x,T y)
        {
            T result=func(x,y);//调用泛型委托中的方法,该方法自己在主函数中边声明,边调用
            Console.WriteLine(result);
        }
    }
}

FangFa<int>((int a, int b)=>{ return a * b; },100,200);

可以将里面的int省去,因为100,200明显是整数,也就是T是int整数。系统自己能推断出来。所以写int多余了,可以将此代码写成:

FangFa((a, b)=>{ return a * b; },100,200);

;