• C# 委托与事件有啥区别?


    一.委托和事件的差别在哪?

    请各位思考一个问题,委托与事件功能几乎相同,委托能干的事件也能干,反之亦然。那为啥还要分别弄出两个来呢?

    (如果你是在学校学的晕头转向的可怜兄弟,那就继续往下看吧,别直接跳到三了)

    二.委托

    说的直白一点,你可以把委托当C++中的函数指针来用。同返回值类型,同参数列表。

    举个例子:

    using System;
    
    namespace ConsoleApp1
    {
        public delegate int Mydel(int w,int d);//声明委托
    
        class Company
        {
            public int yuanTong(int Weight, int Distance)
            {
                //假装经过繁杂计算
                int res = 10;
                Console.WriteLine($"圆通费用:{res}");
                return res;
            }
            public int shenTong(int Weight, int Distance)
            {
                //假装经过繁杂计算
                int res = 8;
                Console.WriteLine($"申通费用:{res}");
                return res;
            }
            public int shunFeng(int Weight, int Distance)
            {
                //假装经过繁杂计算
                int res = 15;
                Console.WriteLine($"顺丰费用:{res}");
                return res;
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                Company company = new Company();
                //实例化委托
                Mydel mydel;
                mydel = company.yuanTong;
                int res=mydel(10, 12);
                mydel = company.shenTong;
                res = mydel(10, 12);
    
                //多播委托
                mydel += company.shunFeng;
                Console.WriteLine();
                res = mydel(10, 12);
    
                /*
                 结果是:
                 圆通费用:10
                 申通费用:8
                 
                 申通费用:8
                 顺丰费用:15
                 */
            }
        }
    }
    View Code

    实际上还可以这么写

    Mydel mydel = new Mydel(company.yuanTong);

    注释里说实例化,这new一个咋这么像一个类呀?它不会...

    为了解决你心中的疑惑,我们看看反编译结果

     你的猜测很正确,委托就是一个类。

    三.事件和委托啥区别?

    上例多播委托也可用事件做到,这里将事件发布方法写到另外一个类里了,读者可将其也放入Company类,效果是一样的。

    using System;
    
    namespace ConsoleApp1
    {
        public delegate int Mydel(int w,int d);//声明委托
        //货物类 发生事件  发布者
        class Cargo
        {
            public int Weight { get; set; }
            public int Distance { get; set; }
            //声明一个事件
            public event Mydel Cal;
            public void Send()
            {
                if(Cal!=null)
                {
                    //触发事件
                    Cal(this.Weight, this.Distance);
                }
            }
        }
        //公司类 处理事件 订阅者
        class Company
        {
            //定义事件处理程序
            public int yuanTong(int Weight, int Distance)
            {
                //假装经过繁杂计算
                int res = 10;
                Console.WriteLine($"圆通费用:{res}");
                return res;
            }
            public int shenTong(int Weight, int Distance)
            {
                //假装经过繁杂计算
                int res = 8;
                Console.WriteLine($"申通费用:{res}");
                return res;
            }
            public int shunFeng(int Weight, int Distance)
            {
                //假装经过繁杂计算
                int res = 15;
                Console.WriteLine($"顺丰费用:{res}");
                return res;
            }
           
        }
        class Program
        {
            static void Main(string[] args)
            {
                Company company = new Company();
                Cargo cargo = new Cargo();
                //订阅事件
                cargo.Cal += company.yuanTong;
                cargo.Cal += company.shenTong;
                cargo.Cal += company.shunFeng;
                
                cargo.Send();
                /*
                 结果是:
                 圆通费用:10
                 申通费用:8
                 顺丰费用:15
                 */
            }
        }
    }
    View Code

    这样好像委托和事件没什么区别,委托能做的事件也能做,事件能做的委托也能做。

    还是那个问题,委托与事件功能几乎相同,委托能干的事件也能干,反之亦然。那为啥还要分别弄出两个来呢?

    我们还是来看看反编译结果

    这个Combine应该不用解释了吧。结论就是:没啥区别,它实际上事件是微软的一个语法糖。你可以把他当作C++里面的函数指针数组。

      

      

  • 相关阅读:
    网页的尺寸
    前端大杂烩总结
    vscode 2.0 配置
    关于node 版本的一个奇葩的问题 :HPE_UNEXPECTED_CONTENT_LENGTH error #3103
    ADO.NET 增删改查的基本用法
    面向对象 类库 委托
    三大特性:封装,继承,多态
    面向对象 抽象类 多态
    SQL数据库基础(九)
    SQL数据库基础(八)
  • 原文地址:https://www.cnblogs.com/AD-milk/p/12545621.html
Copyright © 2020-2023  润新知