前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C# 学习笔记(6)—— 委托

C# 学习笔记(6)—— 委托

作者头像
Karl Du
发布2023-10-20 18:48:40
发布2023-10-20 18:48:40
24800
代码可运行
举报
文章被收录于专栏:Web开发之路Web开发之路
运行总次数:0
代码可运行

委托是什么

委托是 C# 独有的概念,委托的诞生是为了解决将函数作为参数去传递

是的,我们可以像下面这里 name 一样去传递函数了

代码语言:javascript
代码运行次数:0
运行
复制
public void test(string name)
{
    Console.WriteLine(name);
}

public void test(? func)
{
    func();
}

那我可以理解为委托是一个新类型吗?

委托的本质

准确的说,委托是一个类

代码语言:javascript
代码运行次数:0
运行
复制
public delegate void DelegateTest(int param);

// 最终翻译成一个类
public class DeletgateTest : System.MulticastDelegate
{
    // ....
}

所以我们可以对委托去 new,它不就是一个类么

代码语言:javascript
代码运行次数:0
运行
复制
public delegate void DelegateTest(int param);

public void test()
{
    DelegateTest del = new DelegateTest(Print);
    del.invoke(1);
}

public void Print(int param)
{
    Console.WriteLine(param);
}

委托的应用

一个日志记录实例,可以通过委托的方式去更改日志输出方式

代码语言:javascript
代码运行次数:0
运行
复制
class Program
{
    static void Main(string[] args)
    {
        var logger = new Logger();
        logger.Debug("测试1");

        var logger2 = new Logger(msg => Console.WriteLine($"{DateTime.Now}: {msg}"));
        logger2.Debug("测试2");
        Console.ReadKey();
    }
}

public delegate void OutPutAction(string msg);
public class Logger
{
    public OutPutAction Output;

    public Logger()
    {
        Output = new OutPutAction((msg) => Console.WriteLine(msg));
    }

    public Logger(OutPutAction outPutAction)
    {
        Output = outPutAction;
    }

    public void Debug(string msg)
    {
        Output(msg);
    }
}

委托链

签名说的都是委托封装一个方法的情况,其实委托支持封装多个方法。C# 中把封装多个方法的委托称作委托链或多路广播委托

委托链的使用

委托链其实就是委托类型,只是委托链把多个委托链接在一起而已,也就是说,我们把链接了多个方法的委托称为委托链或多路广播委托

代码语言:javascript
代码运行次数:0
运行
复制
class Program
{
    static void Main(string[] args)
    {
        var logger = new Logger();
        logger.Output += msg => Console.WriteLine(msg);
        logger.Output += msg => Console.WriteLine($"{DateTime.Now}: {msg}");
        logger.Debug("测试1");
        Console.ReadKey();
    }
}

public delegate void OutPutAction(string msg);
public class Logger
{
    public OutPutAction Output;

    public void Debug(string msg)
    {
        Output(msg);
    }
}

从以上代码,我们通过"+"运算符,我们能将多个委托对象链接对象链接到一个委托对象实例上,使其称为多路广播实例。在调用委托链时,被绑定到委托链中的每个委托都会被执行

从委托链中移除委托

既然能用 “+” 运算符把委托链接到一个委托对象实例上,自然也能用 “-” 运算符将某个委托从委托链对象上移除。请看下面示例代码

代码语言:javascript
代码运行次数:0
运行
复制
class Program
{
    static void Main(string[] args)
    {
        var logger = new Logger();
        var myDelegate = new OutPutAction((msg) => Console.WriteLine(msg));
        logger.Output += msg => Console.WriteLine($"{DateTime.Now}: {msg}");
        logger.Output += myDelegate;
        logger.Output -= myDelegate;
        logger.Debug("测试1");
        Console.ReadKey();
    }
}

public delegate void OutPutAction(string msg);
public class Logger
{
    public OutPutAction Output;
    public void Debug(string msg)
    {
        Output(msg);
    }
}

归纳总结

委托是很多特性的基础,比如“事件”都是建立在委托之上的,前期如果实在不能理解,也别去钻牛角尖。先尝试写一两个示例,会写会用,接着往后看吧

常见面试题

委托是什么

委托是一个密封类,可以看成是一个函数指针,与指针不同的是我们知道它的返回类型和参数类型。委托类可以包含对多个方法的引用

为什么要用委托

  1. 开启一个新线程
  2. 将方法作为参数传递
  3. 事件,点击按钮的时候根据绑定的方法去调用

.Net 默认的委托类型有哪些

  1. Func 委托类型
  2. Action 委托类型
  3. Predicate 委托类型

多播委托是什么

这个委托包含多个方法叫多播委托

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/07/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 委托是什么
  • 委托的本质
  • 委托的应用
  • 委托链
    • 委托链的使用
    • 从委托链中移除委托
  • 归纳总结
  • 常见面试题
    • 委托是什么
    • 为什么要用委托
    • .Net 默认的委托类型有哪些
    • 多播委托是什么
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档