Csharp-委托

Csharp-委托

委托(Delegate):是一种引用类型的变量,用于存储某个方法的引用地址

  • 定义委托
  • 声明委托变量
  • 关联方法
  • 调用委托
namespace HelloWorld
{
    internal class Program
    {
        // 定义一个委托
        public delegate int Calculate(int x, int y);

        public static int Add(int x, int y)
        {
            return x + y;
        }

        public static int Multiply(int x, int y)
        {
            return x * y;
        }
        static void Main(string[] args)
        {
            
            // 定义委托的同时关联方法 
            var add = new Calculate(Add);
            var multiply = new Calculate(Multiply);

            // 执行方式1:通过Calculate变量名.Invoke执行方法
            Console.WriteLine(add.Invoke(1, 2));

            // 执行方式2:通过Calculate变量名()执行方法
            Console.WriteLine(multiply(1, 2));
        }
    }
}

简而言之,委托定义了可以由其引用的方法的类型。这意味着你可以通过使用委托来创建指向函数的引用,并可以在运行时调用该函数

这样会使项目解耦合,使类之间的关系不那么密切,大幅提升了代码的复用率


委托的多播

委托并不是只能够绑定唯一的方法去执行,我们可以通过多播委托的方式让一条委托的调用去执行多个方法

多播委托的返回值是最后一个子委托执行方法的返回值

namespace Demo02
{
    internal class Program
    {
        // 声明一个委托
        public delegate int Calculate(int x, int y);

        public static int Add(int x, int y)
        {
            Console.WriteLine(x + y);
            return x + y;
        }

        public static int Multiply(int x, int y)
        {
            Console.WriteLine(x * y);
            return x * y;
        }

        static void Main(string[] args)
        {
            // 声明多个cal 作为子委托对象
            var cal1 = new Calculate(Add);
            var cal2 = new Calculate(Multiply);
            var cal3 = new Calculate(Add);

            // 声明一个cal作为主委托对象
            Calculate cal = null;
            // 通过+=号将子委托对象累加到主委托对象中
            cal += cal1;
            cal += cal2;
            cal += cal3;
            // 通过主委托对象调用方法,其子委托依次调用其关联方法
            cal(1, 2);
        }
    }
}

还有一些其他的多播委托的创建方式

Calculate cal = cal1 + cal2 + cal3;
Calculate cal = cal1;
cal += cal2;
cal += cal3;

相同的,我们可以通过-=符号对子委托进行删减

// 声明多个cal 作为子委托对象
var cal1 = new Calculate(Add);
var cal2 = new Calculate(Multiply);
var cal3 = new Calculate(Add);

// 声明一个cal作为主委托对象
Calculate cal = null;
// 通过+=号将子委托对象累加到主委托对象中
cal += cal1;
cal += cal2;
cal += cal3;
// 通过-=号将子委托对象从主委托对象中删减
cal -= cal3;

直接添加方法到委托

我们除了声明子委托添加到主委托的方式,还可以直接将方法添加到主委托中

private static void Main(string[] args)
{

    // 声明一个cal作为主委托对象
    Calculate? cal = null;
    cal += Program.Add;
    cal += Program.Multiply;
    cal += Program.Add;

    cal(1, 2);
}

遍历委托

委托的Api:GetInvocationList可以查看主委托中包含的所有子委托,其返回值是一个委托数组

Calculate? cal = cal1 + cal2 + cal3;

foreach (Calculate c in cal.GetInvocationList())
{
    // 循环遍历每一个cal执行方法,就可以打印每一个委托方法的返回值了
    int result = c(1, 1);
    Console.WriteLine(result);
}

总结

委托定义好了一个方法的返回值和参数列表,通过Lambda可以快速的实现其中的方法执行逻辑,将Lambda表达式赋值给这个委托引用类型定义的变量,即可完成一次对方法的逻辑的定义