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

Por lo tanto, siempre tenemos que transmitir (CallBack) Delegate.Remove (callbackMethodsChain, cbM1); para eliminar delegado de la cadena. No es obviamenteEliminando delegados de la cadena

+5

¿Cuál es la pregunta? – Konamiman

Respuesta

12

Un delegado es inmutable, lo que significa que no puede cambiarlo. Cualquier método que parece cambiarlo, como "agregar" o "restar" de él, en realidad devuelve un nuevo delegado con los cambios.

Así que esto no iba a funcionar:

a.Remove(b); 

pero esto sería:

a = a.Remove(b); 

en términos de llamar al método Remove que es.

Tenga en cuenta que la siguiente sintaxis hace lo correcto:

a -= b; 

Por esta razón, después de llamar a quitar, que aún se observa el código de llamada del delegado que aparentemente apartada, todavía estás llamando el delegado originales cadena con ese delegado presente.

1

Algunos Otros puntos son

se permite

duplicados en su delegado es decir, su delegado puede tener algo como [CBM1, CBM2, CBM2, cbM3]

Si tienen grupo Método [CBM1, CBM2 , cbM3, cbM4, cbM5, CBM1, CBM2] y realizar alguna operación como [CBM1, CBM2, cbM3, cbM4, cbM5, CBM1, CBM2] - [CBM1, CBM2] por lo que recibirá [CBM1 , cbM2, cbM3, cbM4, cbM5]

Si tienen [CBM1, CBM2, cbM3, cbM4, cbM5] y realizar alguna operación como [CBM1, CBM2, cbM3, cbM4, cbM5] - [CBM1, cbM5] obtendrá [CBM1, cbM2, cbM3, cbM4, cbM5]

Cuestiones relacionadas