委托的作用和性能讨论delegate

委托绝对算是C#中一个非常重要和新颖的概念。可以直观的理解成一个安全的函数指针。

delegate实际是如何工作的呢?

delegate int MyDelegate(int x, int y);

//生成自动化的类代码如下

sealed class MyDelegate : System.MulticastDelegate
{
    public int Invoke(int x,int y);
    //...还有其他代码
}

public class MulticastDelegate : Delegate 
{
    //todo 其他代码
}

public abstract class Delegate 
{
    public Method Method {get;}
    public object Target {get;}
    //todo 其他代码
}

系统会自动生成一个叫做MyDelegate的sealed类。而这个类中有一个和我们定义的函数类型完全匹配的Invoke方法。

此外,我们可以看到底层是保存有函数的引用(Method),以及调用对象的(Target,如果是static函数调用,Target=null)。

想到了什么?

是不是感觉,delegate实际就是保存了函数地址和引用对象,然后在Invoke函数中完成一次反射调用就完了。

但是实际上delegate的性能大大优于反射,仅仅小幅弱于普通函数调用。

原因可以参考 https://bbs.csdn.net/topics/390855774

我们什么时候可以用到delegate

前几天看到一个朋友推荐的文档,C#中无delegate,不谈架构。

确实很有道理,C#中,如果涉及跨dll的fe封装或是assambly内跨层次的封装和调用,需要极大程度的运用两种语法(delegate和interface

delegate可以实现类似回调的功能,比如winform程序的button_Click事件就是一个delegate,在底层(.netFX中)定义这个委托的类型,上层如果注册赋值了这个回调,在事件触发时,注册的函数就会受到调用。

interface则是实现了一种基于契约(contract)的编程方式。底层编码过程中,只是假定会有某个履行这种契约的对象可以与自己进行交互,但这个对象具体是什么类型或有什么细节并不知道。上层在使用底层功能时,只需要创建一个符合底层需求(实现了这个interface的类型)的对象,就可以正常使用底层组件了。

实际应用的例子

类似像腾讯的游戏AI框架behavic,我们需要在底层定义完成IBaseUnit等这样的接口,上层再去实现他。AI框架仅仅需要知道IBaseUnit,而不需要关注他的实现方式。

此外,我们有一套技能编辑器,大致的功能就是策划可以通过写脚本的方式(C#)来完成一些技能流程的定制。比如,循环伤害n次,等待几秒,再上一个buff。通用类似于Behavic,我们在底层定义接口对象,策划就可以通过调用结构对象的方法来完成脚本编写了。

for(int i=0;i<10;i++)
    self.Attack(target);
self.Wait(500); //ms
self.AddBuff(target, 13000000, 2000);

这么做,还带来了一个额外的好处。定义接口行为和实现行为可以不同步进行。这样的是实好处是,实际功能没还有支持完成,策划已经可以把相关流失配置完成了,两边可以并行工作,不受影响。

你可能感兴趣的:(C#,游戏,delegate,C#,委托,设计模式)