2012-05-22 17 views
5

¿Hay alguna diferencia entre estas dos implementaciones?¿Diferencia entre dos implementaciones de eliminación?

1:

public class SMSManager : ManagerBase 
{ 
    private EventHandler<SheetButtonClickEventArgs> _buttonClickevent; 

    public SMSManager(DataBlock smsDataBlock, DataBlock telephonesDataBlock) : 
     base(smsDataBlock) 
    { 
     _buttonClickevent = new EventHandler<SheetButtonClickEventArgs>(OnButtonClick); 
     SheetEvents.ButtonClick += _buttonClickevent; 

    } 

    public override void Dispose() 
    { 
     base.Dispose(); 
     if (_buttonClickevent != null) 
     SheetEvents.ButtonClick -= _buttonClickevent; 
    } 
} 

2:

public class SMSManager : ManagerBase 
{ 
    public SMSManager(DataBlock smsDataBlock, DataBlock telephonesDataBlock) : 
     base(smsDataBlock) 
    { 
     SheetEvents.ButtonClick += new EventHandler<SheetButtonClickEventArgs>(OnButtonClick); 
    } 

    public override void Dispose() 
    { 
     base.Dispose(); 
     SheetEvents.ButtonClick -= new EventHandler<SheetButtonClickEventArgs>(OnButtonClick); 
    } 
} 

El primero parece ser más correcto que el segundo en lo que respecta a las pérdidas de memoria. Pero, ¿es realmente correcto?

+0

No olvide marcar una respuesta como la respuesta, ayuda a enriquecer el contenido de este sitio. –

Respuesta

5

En resumen, la segunda parte del código es correcta y segura (incluso si no hay controladores registrados).

considerar esta aplicación de ejemplo: grabados

namespace ConsoleApplication61 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var f = new Foo(); 
      f.MyEvent += new EventHandler(Handler); 
      f.Trigger(); 
      f.MyEvent -= new EventHandler(Handler); 
      f.Trigger(); 
      Console.Read(); 
     } 

     static void Handler(object sender, EventArgs e) 
     { 
      Console.WriteLine("handled"); 
     } 
    } 

    class Foo 
    { 
     public event EventHandler MyEvent; 
     public void Trigger() 
     { 
      if (MyEvent != null) 
       MyEvent(null, null); 
     } 
    } 
} 

esta muestra "manejado" una vez.

Por lo tanto, en su ejemplo, son funcionalmente iguales y ambos funcionarán según sea necesario. La eliminación de un controlador que no se ha agregado también es una acción segura, simplemente no encuentra nada que eliminar y no hace nada.

a lo dispuesto en los comentarios, la respuesta de Marc entra en más detalles:

Unregister events with new instance of the delegate


controladores de eventos con los métodos anónimos

Vale la pena señalar que los controladores de eventos en forma No se garantiza que las expresiones lambda impongan la unicidad basada en la instancia y la firma del método. Si tiene que darse de baja un método anónimo, que sea necesario para promover a un método o mantener una referencia al método anónimo para su uso posterior:

Func<object, EventArgs> meth = (s, e) => DoSomething(); 

myEvent += meth; 
myEvent -= meth; 

Jon Skeet entra en detalles responder a esta y es probable que hace un mejor trabajo de él que yo :-)

How to remove a lambda event handler


Un Refactoring Leve

Me gustaría refactorizar a lo siguiente:

public class SMSManager : ManagerBase 
{ 
    public SMSManager(DataBlock smsDataBlock, DataBlock telephonesDataBlock) 
     : base(smsDataBlock) 
    { 
     SheetEvents.ButtonClick += OnButtonClick; 
    } 

    public override void Dispose() 
    { 
     SheetEvents.ButtonClick -= OnButtonClick; 
     base.Dispose(); 
    } 
} 
+0

Ver Marcs [respuesta] (http://stackoverflow.com/a/714126/95573) – SwDevMan81

+0

@ SwDevMan81 Bingo! He estado buscando esa información, ta. –

+0

@ SwDevMan81: Hoy aprendí. (Además, es Marc, no Mark.) – BoltClock