2011-08-16 4 views
12

Ho scaricato ReSharper e mi dice di cambiare questa linea:Rimuovere la chiamata del costruttore delegato ridondante?

dispMap.OnDraw += new EventHandler(dispMap_OnDraw); 

Per essere questa linea:

dispMap.OnDraw += dispMap_OnDraw; 

Perché la prima linea è una "chiamata del costruttore delegato ridondante."

È vero? Nel codice di progettazione generato automaticamente per i moduli la sintassi si basa sul primo pezzo di codice e quando si digita dispMap.OnDraw += e si colpisce TAB l'IDE genera automaticamente new EventHandler(dispMap_OnDraw)

Sono solo curioso di questo. ReSharper ha un punto?

risposta

10

Sì, questo è corretto. L'ho fatto in diversi casi.

La chiamata del costruttore delegato deve essere implicita; il tipo può essere desunto da OnDraw e convalidato con la firma del metodo di dispMap_OnDraw.

Inoltre, una citazione da this MSDN article appare rilevante:

Perché l'operatore + = semplicemente concatena l'interno lista invocazione di un delegato a un altro, è possibile utilizzare il + = per aggiungere un metodo anonimo . Si noti che con la gestione degli eventi anonimi, non è possibile rimuovere il metodo di gestione degli eventi utilizzando l'operatore - = a meno che il metodo anonimo sia stato aggiunto come gestore prima di memorizzarlo in un delegato e quindi registrare tale delegato con l'evento.

credo che l'istanza delegato viene creata in entrambi i casi, ma dal momento che non si dispone di un riferimento oggetto per il delegato quando implicitamente un'istanza, non è possibile rimuovere con l'operatore -=.

5

Ha un punto. La seconda riga è una scorciatoia per la prima. A seconda degli standard/convenzioni di codifica, è possibile utilizzare uno dei due, ma il primo aggiunge molto rumore.

0

funziona, ho DevExpress e mi dice lo stesso!

3

Se si confronta l'IL generato in entrambi i casi, si vedrà che sono uguali. Ecco entrambi i casi in C#, e l'IL risultano in

Esempio C#:.

namespace EventTest 
{ 
    public class Publisher 
    { 
     public delegate void SomeEvent(object sender); 
     public event SomeEvent OnSomeEvent; 
     public event SomeEvent OnOtherEvent; 
    } 

    public class Subscriber 
    { 
     public Subscriber(Publisher p) 
     { 
      p.OnSomeEvent += new Publisher.SomeEvent(Respond); 
      p.OnOtherEvent += Respond; 
     } 

     public void Respond(object sender) 
     { 

     } 
    } 
} 

Ecco il IL per il costruttore. Prestare attenzione alle linee IL_000a tramite IL_0028.

.method public hidebysig specialname rtspecialname 
     instance void .ctor(class EventTest.Publisher p) cil managed 
{ 
    // Code size  48 (0x30) 
    .maxstack 8 
    IL_0000: ldarg.0 
    IL_0001: call  instance void [mscorlib]System.Object::.ctor() 
    IL_0006: nop 
    IL_0007: nop 
    IL_0008: ldarg.1 
    IL_0009: ldarg.0 
    IL_000a: ldftn  instance void EventTest.Subscriber::Respond(object) 
    IL_0010: newobj  instance void EventTest.Publisher/SomeEvent::.ctor(object, 
                      native int) 
    IL_0015: callvirt instance void EventTest.Publisher::add_OnSomeEvent(class EventTest.Publisher/SomeEvent) 
    IL_001a: nop 
    IL_001b: ldarg.1 
    IL_001c: ldarg.0 
    IL_001d: ldftn  instance void EventTest.Subscriber::Respond(object) 
    IL_0023: newobj  instance void EventTest.Publisher/SomeEvent::.ctor(object, 
                      native int) 
    IL_0028: callvirt instance void EventTest.Publisher::add_OnOtherEvent(class EventTest.Publisher/SomeEvent) 
    IL_002d: nop 
    IL_002e: nop 
    IL_002f: ret 
} 

Conclusione: Non vedo alcun motivo per modificare il codice, sono equivalenti.