2012-08-16 14 views
17

Actualización: Esto ocurre cuando la opción de análisis de código "Suprimir resultados del código generado (solo administrado)" está desactivada, y el conjunto de reglas está establecido en "Reglas de la guía de diseño básico de Microsoft".¿Por qué un controlador de eventos delegar vacío causa una advertencia CA1061?

En 2013-04-26, Microsoft confirmó que se trata de un error, pero no lo reparará ni en esta ni en la próxima versión de Visual Studio.

Link to MS Connect item

frecuencia Inicializamos controladores de eventos con un delegado de vacío para evitar la necesidad de comprobar los nulos. Ej .:

public EventHandler SomeEvent = delegate {}; 

Sin embargo, desde que comenzó a compilar algunas de nuestro código en Visual Studio 2012 (RTM), estoy notando una gran cantidad de eventos en las clases derivadas ahora están desencadenando CA1601: Do not hide base class methods advertencias en Visual Studio Análisis de código de 2012.

He aquí una muestra que dará lugar a la advertencia:

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: En VS2012 el aviso se activa cuando se compila en cualquiera .NET 4.5 o .NET 4.0. La misma muestra no activa la advertencia en VS2010.

Por motivos de rendimiento, ¿hay alguna razón legítima por la que no deberíamos inicializar eventos con delegados vacíos? El supuesto por defecto es que es probable que sólo una peculiaridad en el análisis en Visual Studio 2012.

Aquí está el resultado de análisis de código para aquellos que no tienen acceso a VS2012 aún:

CA1061 No oculte Métodos de clase base Cambie o elimine 'Class2.Class2()' porque oculta un método de clase base más específico: 'Class1.Class1()'. TestLibrary1 Class1.cs 14

Adición: encontré que la opción de "reprimir resultados de código generado" en el análisis de código está apagado.

Además, he encontrado que esto parece ocurrir cuando el controlador de eventos en el tipo base es a la vez:

  • un delegado que no sea manejador de sucesos o manejador de sucesos -y-
  • eventos, tanto en la clase base y la clase derivada se inicializa utilizando un método anónimo o un delegado vacío (ya sea en línea o en el constructor).

Posible relevancia: estamos ejecutando Visual Studio 2012 RTM, que se instaló en el lugar sobre la versión candidata.

+0

¿Está inicializando sus Manejadores de eventos de esta manera para evitar tener que hacer comprobaciones nulas antes de dispararlos? –

+0

Esa es la razón predominante, sí. – Sean

+0

Me parece una rareza de VS 2012. Si estaba sobrescribiendo a un delegado en la clase base, podría verlo, pero tal como está, no parece coincidir con la descripción de CA1061: http : //msdn.microsoft.com/en-us/library/ms182143.aspx –

Respuesta

4

El problema es que el compilador de C# genera un delegado estático utilizado para inicializar el delegado de su instancia, que se denomina igual para Class1 y Class2.

Class1.CS$<>9__CachedAnonymousMethodDelegate1 existe para su uso por el constructor de Clase 1 para inicializar PropertyCancelled, mientras Class2.CS$<>9__CachedAnonymousMethodDelegate1_ existe para su uso por el constructor de clase 2 para inicializar SelectionCancelled.

Desafortunadamente, el compilador de C# no incluye algún tipo de registro de la clase padre 'generado automáticamente' cuando se decide cómo nombrar las 'cosas' generadas automáticamente para una clase secundaria. Agriete esto abierto en ILDasm y el problema se vuelve inmediatamente obvio. Es bueno saber que encontraste una solución alternativa. La advertencia es completamente razonable de ignorar, dado que no se puede tocar a los delegados estáticos de C#, gracias a los nombres que no cumplen con C#.

+1

Esa es ciertamente una explicación racional de lo que está sucediendo, pero no explica por qué solo ha comenzado con la versión más reciente de Visual Studio. Sin embargo, he encontrado muchas otras rarezas en Code Analysis de 2012 en la última semana, todo sobre métodos anónimos relacionados con los manejadores de eventos y consultas LINQ, así que gracias por la información. – Sean

Cuestiones relacionadas