2009-11-11 17 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; 
    } 
} 

Tak więc, zawsze musimy oddać delegata (CallBack). Odwołać (callbackMethodsChain, cbM1); aby usunąć delegata z łańcucha. To nie jest oczywiste.Usuwanie delegatów z łańcucha

+5

Na czym polega pytanie? – Konamiman

Odpowiedz

12

Delegat jest niezmienny, co oznacza, że ​​nie możesz go zmienić. Wszelkie metody, które wydają się go zmieniać, np. "Dodawanie" do niego lub "odejmowanie" od niego, w rzeczywistości zwraca nowego delegata ze zmianami.

Więc to nie będzie działać:

a.Remove(b); 

ale to:

a = a.Remove(b); 

chodzi o wywołanie metody Remove to jest.

pamiętać, że poniższe składnia robi słusznie:

a -= b; 

Dlatego, po wywołaniu Usuń, że nadal obserwować kod wywołujący delegat ci pozornie usunięte, nadal jesteś wzywającą oryginalny delegata łańcucha z obecnym delegatem.

1

Niektóre inne punkty są

Duplikaty są niedozwolone w Twojej delegata tj swoim delegatem może mieć coś [cbM1, CBM2, CBM2, cbM3]

jeśli u mieć grupę sposobem [cbM1, CBM2 , cbM3, cbM4, cbM5, cbM1, CBM2] i wykonać jakąś operację jak [cbM1, CBM2, cbM3, cbM4, cbM5, cbM1, CBM2] - [cbM1, CBM2] wtedy dostaniesz [cbM1 , cbM2, cbM3, cbM4, cbM5]

Jeśli u mają [cbM1, CBM2, cbM3, cbM4, cbM5] i wykonać kilka operacji, takich jak [cbM1, CBM2, cbM3, cbM4, cbM5] - [cbM1, cbM5] dostaniesz [cbM1, cbM2, cbM3, cbM4, cbM5]