从链中删除委托

时间:2009-11-11 08:27:45

标签: c# .net clr

class Program
{
    internal delegate int CallBack(int i);

    static void Main(string[] args)
    {
        CallBack callbackMethodsChain = null;
        CallBack cbM1 = new CallBack(FirstMethod);
        CallBack cbM2 = new CallBack(SecondMethod);

        callbackMethodsChain += cbM1;
        callbackMethodsChain += cbM2;

        Delegate.Remove(callbackMethodsChain, cbM1);
    /*L_0039: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class  [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
        L_003e: pop 
        L_003f: ldloc.0 */

        Trace.WriteLine(callbackMethodsChain.GetInvocationList().Length);
        //Output: 2 **WTF!!!**


        callbackMethodsChain -= cbM1;
        /*
    L_0054: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Remove(class   [mscorlib]System.Delegate, class [mscorlib]System.Delegate)
          L_0059: castclass Generics.Program/CallBack
          L_005e: stloc.0 
          L_005f: ldloc.0 
        */
        Trace.WriteLine(callbackMethodsChain.GetInvocationList().Length);
        //Output: 1
    }

    private static int FirstMethod(int test)
    {            
        Trace.WriteLine("FirstMethod");
        return test;
    }

    private static int SecondMethod(int test)
    {
        Trace.WriteLine("SecondMethod");
        return test;
    }
}

所以,我们总是需要强制转换(CallBack)Delegate.Remove(callbackMethodsChain,cbM1);从链中删除委托。这显然不是。

2 个答案:

答案 0 :(得分:12)

委托是不可变的,这意味着你无法改变它。任何似乎改变它的方法,比如“添加”它或“从中减去”,实际上会返回一个带有更改的新委托。

所以这不起作用:

a.Remove(b);

但这会:

a = a.Remove(b);

就调用Remove方法而言。

请注意,以下语法是正确的:

a -= b;

这就是为什么在调用Remove之后,你仍然会观察调用你看似被删除的委托的代码,你仍然会调用原来的代理链,并且该代表在场。

答案 1 :(得分:1)

其他一些观点

允许重复     代表,即你的代表可以     有类似的东西     [CBM1,CBM2,CBM2,CBM3]

如果你有方法组[cbM1,cbM2,     cbM3,cbM4,cbM5,cbM1,cbM2]和你     执行一些操作     [CBM1,CBM2,     cbM3,cbM4,cbM5,cbM1,cbM2] -     [cbM1,cbM2]然后你会得到     [cbM1,cbM2,cbM3,cbM4,cbM5]

如果你有[cbM1,cbM2,     cbM3,cbM4,cbM5]并执行一些操作,如[cbM1,cbM2,     CBM3,CBM4,cbM5] - [CBM1,cbM5]     你会得到[cbM1,cbM2,cbM3,cbM4,cbM5]