深入解析委托

本文通过一个生动的寝室场景,介绍了 C# 中委托的基本概念及其应用场景,包括委托的定义、实例化、调用过程及委托链的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

先来到一个场景,小明、欧阳轰、王麻子是一个寝室的,有一天小明去吃午饭,欧阳轰说:帮我带一瓶饮料呗。这里,可以看出一个小小的委托关系,小明是欧阳轰的被委托人(经纪人),欧阳轰不用自己去做,请一个人代替他去做。这个时候王麻子也不想下楼了说:随便帮我带一个饭,还来一瓶饮料吧,我不挑食。这里的被委托人可以接受不同的委托人委托的事情,也可以是多件不同的事情。

下面我们用代码实现,这里呢用两种方式调用委托:

class Program
    {
        //定义委托
        public delegate void DelegateBring(string name);
        static void Main(string[] args)
        {
            Ming ming = new Ming();
            //声明委托
            DelegateBring delegateBring;
            //实例化委托
            delegateBring = new DelegateBring(ming.BringDrink);
            //作为参数传入方法
            DelegateReceive(delegateBring, "欧阳轰", "可乐");
            delegateBring += new DelegateBring(ming.BringFood);
            delegateBring("王麻子");

            Console.Read();
        }

        public static void DelegateReceive(DelegateBring delegateBring, string stuName, string Drink)
        {
            //使用传入方法
            delegateBring(stuName);
            Console.WriteLine(" 备注:{0}", Drink);
        }
    }
    class Ming
    {
        public void BringFood(string name)
        {
            Console.WriteLine("帮{0}带饭", name);
        }

        public void BringDrink(string name)
        {
            Console.WriteLine("帮{0}带一瓶饮料", name);
        }
    }

 

输出:

帮欧阳轰带一瓶饮料
 备注:可乐
帮王麻子带一瓶饮料
帮王麻子带饭

 

这里,我们从刚刚的示例和代码中分析得出以下结论:

1.我们把相同的操作封装起来,重复使用,这很符合面向对象编程的思想,减少重复代码量

 

 

2.通过委托,我们把方法当作参数传入使用者,这里的小明做的事情可以看作相对的“接口”,这样的设计符合一个面向对象的原则:面对接口编程,不对实现编程

3.我们可以通过委托订阅很多个方法,不需要一个一个的去调用,那么实现这个重要功能的就是委托链(下面解释),这个也是委托的一个重要的特色

 

 

接下来我们了解委托的构造

通过断点我们可以看到我们实例化的delegate是继承System.MulticastDelegate,点开+号看到有个base,这个就是他的继承父类,也就是System.Delegate

 

 

System.Delegate里面有两个很重要的方法:

1.Combine 添加指定的委托,也就是委托订阅常用在多播委托,可以用+=来完成

 

 

2.Remove这个方法跟combine方法相对,是取消某个多播委托上面的委托,通常让委托链上指定的委托为null回收内存,可以用-=来完成

System.MulticastDelegate里面的一个方法和两个属性,我们通过调试的监视窗口来观察他们

 

 

Method指向将要调用的方法的地址

 

 

Target这个存储的是指明调用方法所在的实例对象,如果委托调用的是一个静态方法,那么这个字段就是一个null,如果调用的是一个实例方法,那么它就是这个方法的对象

GetInvocationList()这个方法是获取多播委托的数组

 

 

接下来通过断点查看这两个类里面的构造

这里我们可以看到关键的几个属性方法

 

 

_target:对应的是Target属性

_methodPtr:对应的是Method属性,这里显示的是一串数字,可以理解是这个方法的一个回调指针

 

 

_invocationList:对应的是GetInvocationList()委托链

那么我们这里在最后面加入一段遍历这个委托链的代码,然后看看执行委托的顺序吧

for (int i = 0; i < delegateBring.GetInvocationList().Count(); i++)
            {
                Console.WriteLine(delegateBring.GetInvocationList()[i].Method.Name);
            }

 

最后输出:

BringDrink
BringFood

 

那么查看了这么多信息,我们根据这些特性画一画这个委托链吧

总结:从委托的作用,委托的由来,再到一步步的编译和监控,再到后面的遍历委托链,大家应该对委托有了一个更深的了解。还是那句,习而简之。希望对大家有帮助

 

写在最后:这里没有用到反编译工具,也没有贴IL,我感觉这个玩意儿没多少人能看懂,也不算是汇编语言,所以就用这种断点,查看监视的方法简单文雅,准备了一个星期左右,写着写着感觉就成了一个灵魂画家偷笑。最后希望大家指出错误,给予我建议,爱你们,么么哒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值