• 委托探索


    一直对于委托理解有点朦胧,今天一时兴起准备一探究竟。首先要准备的工具就是reflector(反编译器)。

    1 delegate void SayHiDelegate(string name);
    2 void SayNiHao(string name)
    3 {
    4 Console.WriteLine("你好"+name);
    5 }
    6 void SayHello(string name)
    7 {
    8 Console.WriteLine("Hello"+name);
    9 }

    然后我们先这样调用

    1 SayHiDelegate SayHi = null;
    2 SayHi = new SayHiDelegate(SayHello);//这里也可以写成SayHi = SayHello
    3 SayHi += SayNiHao;//这里实际上为SayHi = (SayHiDelegate) Delegate.Combine(SayHi, new SayHiDelegate(SayNiHao))

    然后我们编译下,在反编译下exe文件。来查看Delegate.Combine(SayHi, new SayHiDelegate(SayNiHao))到底是怎么回事?

    1 public static Delegate Combine(Delegate a, Delegate b)
    2 {
    3 if (a == null)
    4 {
    5 return b;
    6 }
    7 return a.CombineImpl(b);
    8 }

    再来查看a.CombineImpl(b)是怎么回事?

    1 protected virtual Delegate CombineImpl(Delegate d)
    2 {
    3 throw new MulticastNotSupportedException(Environment.GetResourceString("Multicast_Combine"));
    4 }

    这里就让我无路可找了,然后我又发现有个virtual关键字,于是就想看看是否有子类override这个方法。(查看它的Derived Type下)看见果然有个子类叫MulticastDelegate在到MulticastDelegate类里面找CombineImpl(Delegate d)方法,果然找到了。

    1 protected sealed override Delegate CombineImpl(Delegate follow);

    打开一看晕了,太长了。有点想放弃看了,想到今天的目的还是忍着头皮看下去。看了许久,查了一些资料。发现MulticastDelegate类两个字段

    1 private IntPtr _invocationCount;
    2 private object _invocationList;

    以及MulticastDelegate继承的Delegate的两个字段

    1 internal IntPtr _methodPtr;
    2 internal object _target;

    大概的意思。

    _invocationList:表示存储当前委托中的方法数目。
    _methodPtr:表示初始化的时候指向的方法
    _target:表示初始化的时候指向方法的对象。即this.SayHi();-->this就为_target,SayHi()就为_methodPtr
    _invocationList:表示存放方法的数组。
    _invocationCount:表示_invocationList个数。

     1 protected sealed override Delegate CombineImpl(Delegate follow)
    2 {
    3 object[] objArray;
    4 int num2;
    5 if (follow == null)
    6 {
    7 return this;
    8 }
    9 if (!Delegate.InternalEqualTypes(this, follow))
    10 {
    11 throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTypeMis"));
    12 }
    13 MulticastDelegate o = (MulticastDelegate) follow;
    14 int num = 1;
    15 object[] objArray2 = o._invocationList as object[];
    16 if (objArray2 != null)
    17 {
    18 num = (int) o._invocationCount;
    19 }
    20 object[] objArray3 = this._invocationList as object[];
    21 if (objArray3 == null)
    22 {
    23 num2 = 1 + num;
    24 objArray = new object[num2];
    25 objArray[0] = this;
    26 if (objArray2 == null)
    27 {
    28 objArray[1] = o;
    29 }
    30 else
    31 {
    32 for (int i = 0; i < num; i++)
    33 {
    34 objArray[1 + i] = objArray2[i];
    35 }
    36 }
    37 return this.NewMulticastDelegate(objArray, num2);


    38
    }
    这是情形一:

    大致的流程:a.CombineImpl(b)
    1. 如果b==null就返回a也就是说b中没有任何方法,那么a+=b自然为a了;
    2. 如果b!=null,那么如果b中的_invokationList没有方法,那么b的方法数为num=1;否则num=_invocationCout;
    3. 然后在计算a的方法总数,如果a==null那么方法总个数num2=num+1,然后在申请一个num2的数组大小,将a,b中的方法所在的委托对象的地址存入。最后在重新生成一个委托作为返回值。










  • 相关阅读:
    网络CCNA基础了解
    KVM 安装 VMware 虚拟机
    [转载]JS浏览器兼容性问题
    java中数组是不是对象?
    [转载]request.getServletPath()方法
    weblogic下更改jsp不生效的解决办法
    java之args[0]
    docker小demo
    eclipse优化
    [转载]oracle建表语句大全
  • 原文地址:https://www.cnblogs.com/hankskfc/p/2228147.html
Copyright © 2020-2023  润新知