2012-08-16 15 views
17

Aggiornamento: Questo errore si verifica quando l'opzione di analisi del codice "Sopprimi risultati dal codice generato (solo gestito)" è disattivata e Set di regole è impostato su "Regole linee guida per la progettazione di base Microsoft".Perché un gestore eventi delegato vuoto causa un avviso CA1061?

In data 2013-04-26, Microsoft ha confermato che si tratta di un errore, ma non lo risolverà in questa o nella prossima versione di Visual Studio.

Link to MS Connect item

Inizializziamo frequentemente gestori di eventi con un delegato vuoto per evitare la necessità di controllare i valori nulli. Es .:

public EventHandler SomeEvent = delegate {}; 

Tuttavia, da quando ha iniziato a compilare alcuni dei nostri codice in Visual Studio 2012 (RTM), sto notando un sacco di eventi in classi derivate sono ora innescando CA1601: Do not hide base class methods avvertenze in Visual Studio analisi del codice del 2012.

Ecco un esempio che attiverà l'allarme:

using System; 
using System.ComponentModel; 

[assembly: CLSCompliant(true)] 

namespace TestLibrary1 
{ 
    public abstract class Class1 
    { 
     public event PropertyChangedEventHandler PropertyChanged = delegate {}; 
    } 

    public class Class2 : Class1 
    { 
     // this will cause a CA1061 warning 
     public event EventHandler SelectionCancelled = delegate { }; 
    } 

    public class Class3 : Class1 
    { 
     // this will not cause a CA1061 warning 
     public event EventHandler SelectionCancelled; 
    } 
} 

Nota: In VS2012 l'avviso viene attivato quando compilato sia in .NET 4.5 o .NET 4.0. Lo stesso campione non attiva l'avviso in VS2010.

Motivi di prestazioni a parte, ci sono motivi legittimi per non inizializzare eventi con delegati vuoti? L'ipotesi di default è che è probabilmente solo un capriccio per l'analisi in Visual Studio 2012.

Ecco il risultato di analisi del codice per coloro che non hanno accesso a VS2012 ancora:

CA1061 non nascondere metodi della classe base Modifica o rimuovi 'Class2.Class2()' perché nasconde un metodo di classe base più specifico: 'Class1.Class1()'. TestLibrary1 Class1.cs 14

Addendum: ho trovato che l'opzione "Elimina i risultati di codice generato" nel analisi del codice è spento.

Inoltre, ho scoperto che questo sembra verificarsi quando il gestore di eventi nel tipo di base è al tempo stesso:

  • un delegato diverso EventHandler EventHandler o -e-
  • eventi sia la classe base e la classe derivata viene inizializzata utilizzando un metodo anonimo o un delegato vuoto (inline o nel costruttore).

Di possibile rilevanza: stiamo eseguendo Visual Studio 2012 RTM, che è stato installato sul posto nel rilascio del candidato.

+0

Stai inizializzando i tuoi EventHandler in questo modo per evitare di dover eseguire controlli null su di essi prima di attivarli? –

+0

Questa è la ragione predominante, sì. – Sean

+0

Mi sembra una parvenza di VS 2012. Se dovessi sovrascrivere un delegato nella classe base, potrei forse vederlo, ma così com'è, non sembra affatto che corrisponda alla descrizione di CA1061: http : //msdn.microsoft.com/en-us/library/ms182143.aspx –

risposta

4

Il problema è che il compilatore C# genera un delegato statico utilizzato per inizializzare il delegato dell'istanza, che è denominato uguale per Class1 e Class2.

Class1.CS$<>9__CachedAnonymousMethodDelegate1 esiste per l'utilizzo da parte del costruttore di Class1 per inizializzare PropertyCancelled, mentre Class2.CS$<>9__CachedAnonymousMethodDelegate1_ esiste per l'utilizzo da parte del costruttore di Class2 per inizializzare SelectionCancelled.

È spiacevole che il compilatore C# non includa una sorta di record della roba generata automaticamente "gen" della classe padre quando si decide come denominare "roba" generata automaticamente per una classe figlio. Rompere questo aperto in ILDasm e il problema diventa immediatamente ovvio. Buono a sapersi che hai trovato un lavoro in giro. L'avviso è del tutto ragionevole da ignorare, dato che non è possibile toccare i delegati statici da C#, grazie alla denominazione non compatibile con C#.

+1

Questa è sicuramente una spiegazione razionale per ciò che sta accadendo, ma non affronta il motivo per cui è stata avviata solo con la versione più recente di Visual Studio. Tuttavia, ho trovato molte altre stranezze nell'analisi del codice del 2012 nell'ultima settimana, tutte relative ai metodi anonimi relativi ai gestori di eventi e alle query LINQ, quindi grazie per l'intuizione. – Sean

Problemi correlati