C#委托基本用法

1、什么是委托
委托类似于C++函数指针,但与指针不同的是,委托是完全面向对象的,是安全的数据类型。
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以把多个方法链接在一起。这样,在事件触发时可同时启动多个事件处理程序。
委托签名不需要与方法精确匹配
2、委托用法

private delegate void NoResult1();//声明一个无参无返回值的委托
private delegate string NoResult2();//声明一个无参有返回值的委托
private delegate void NoResult3(int id, string name);//声明一个有参无返回值的委托
private delegate string NoResult4(int id, string name);//声明一个有参有返回值的委托
private static string d(int id, string name)
{
    Console.WriteLine($"方法d执行id:{id},name:{name}");
    return "d";
}

2.1、常规写法

NoResult4 me4 = new NoResult4(d);

2.2、匿名方式写法

me4 += (id, name) =>
{
    Console.WriteLine($"这是有参有返回值匿名方法简写id:{id},name:{name}");
    return "有参有返回值匿名方法";
};
me4 += delegate(int id, string name){
    Console.WriteLine($"这是有参有返回值匿名方法简写id:{id},name:{name}");
    return "有参有返回值匿名方法";
};

2.3、委托调用

me4.Invoke(1, "张三");

执行结果

3、委托本质
使用ILSpy工具打开我们刚写的代码

如上图所示,我们发现在经过编译器的处理,最终委托会变成一个密封类并且继承MulticastDelegate。既然如此那么我们是不是可以自定义一个类然后继承MulticastDelegate呢?这里卖个关子,有兴趣的同学可自行了解。
 

4、什么时候用委托
举例有如下需求:
根据不同语言实现不同的问候方式(美国人使用英文问题,中国人使用中文问候...)

public void China(string name)
{
    Console.WriteLine($"{name} 你好");
}
public void English(string name)
{
    Console.WriteLine($"hello {name}");
}

实现方式一:

private void SayHi(string name, int type)
{
    switch (type)
    {
        case 1:
            China(name);
            break;
        case 2:
            English(name);
            break;
    }
}


实现方式二:
中国人调用:

China("张三");

美国人调用:

English("Adam Donaldson");

这两种方式有什么缺点呢?
方式一每次添加语言需要添加分支,导致代码不稳定,违背了开闭原则。
方式二如果我们要添加日志或者需要添加其他业务处理,那么我们需要修改所有方法。

委托实现方式:

private delegate void SyaHiDelegate(string name);
private static void SayHiDelegate(string name, SyaHiDelegate method)
{
    Console.WriteLine("写日志");
    method.Invoke(name);
    Console.WriteLine("扩展业务处理");
}

中国人调用:

SyaHiDelegate method = new SyaHiDelegate(China);
SayHiDelegate("张三", method);

美国人调用:

SyaHiDelegate method = new SyaHiDelegate(English);
SayHiDelegate("Adam Donaldson", method);

使用委托的方式可以很好的解决方式一方式二的问题。

猜你喜欢

转载自blog.csdn.net/qq_32109957/article/details/102621914