2009-11-11 8 views
5
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);をキャストする必要があります。デリゲートをチェーンから削除します。明らかにそうではありません。デリゲートをチェーンから削除する

+5

何が問題なのですか? – Konamiman

答えて

12

代理人は不変です。つまり、代理人は変更できません。それに「追加」や「差し引く」のように、それを変更するように見えるメソッドは、実際には変更を加えた新しいデリゲートを返します。

だから、これは動作しないでしょう。

a.Remove(b); 

しかし、これでしょう:あるRemoveメソッドを呼び出すという点で

a = a.Remove(b); 

を。

a -= b; 

あなたはまだあなたが一見削除デリゲートを呼び出すコードを観察すること、削除呼び出した後、あなたはまだ元のデリゲートを呼び出している理由は、これは次の構文が正しいことをしないこと

注意その代表者と連鎖しています。いくつかの他のポイントは

重複がデリゲート、つまり、あなたの デリゲートで許可されている

1

uはメソッドグループ[cbM1、CBM2を持っている場合は のようなもの[cbM1、CBM2、CBM2、cbM3]

を 持つことができます、 cbM3、cbM4、cbM5、cbM1、CBM2]あなたが [cbM1、CBM2、 cbM3、cbM4、cbM5、cbM1、CBM2]のようないくつかの操作を実行 - [cbM1、CBM2]あなたが取得します [cbM1 、cbM2、cbM3、cbM4、cbM5]

uは[cbM1、CBM2、 cbM3、cbM4、cbM5]を持っていて、[cbM1、CBM2、 cbM3、cbM4、cbM5]のようないくつかの操作を実行した場合 - [cbM1、cbM5] あなたは[cbM1を取得します、 cbM2、cbM3、cbM4、cbM5]