c# - orden - ¿Por qué un controlador de eventos de delegado vacío causa una advertencia CA1061?
instanciar un evento c# (1)
Actualización: esto ocurre cuando la opción Análisis de código "Suprimir los resultados del código generado (solo administrado)" está desactivada, y el Conjunto de reglas está configurado en "Reglas de la guía básica de diseño de Microsoft".
El 2013-04-26, Microsoft confirmó que se trata de un error, pero no lo solucionará ni en esta ni en la próxima versión de Visual Studio.
Con frecuencia, los controladores de eventos se inicializan con un delegado vacío para evitar la necesidad de comprobar nulos. P.ej:
public EventHandler SomeEvent = delegate {};
Sin embargo, desde que empecé a compilar parte de nuestro código en Visual Studio 2012 (RTM), noté que muchos eventos en clases derivadas ahora activan CA1601: No oculte las advertencias de los métodos de clase base en el Análisis de Código de Visual Studio 2012.
Aquí hay una muestra que activará 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, la advertencia se activa cuando se compila en .NET 4.5 o .NET 4.0. La misma muestra no activa la advertencia en VS2010.
Aparte de los motivos de rendimiento, ¿hay motivos legítimos por los que no deberíamos estar inicializando eventos con delegados vacíos? La suposición predeterminada es que probablemente sea solo una peculiaridad en el análisis en Visual Studio 2012.
Aquí está el resultado del análisis de código para aquellos que aún no tienen acceso a VS2012:
CA1061 No oculte los 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
Anexo: Encontré que la opción "Suprimir los resultados del código generado" en el análisis de código está desactivada.
Además, encontré que esto parece ocurrir cuando el controlador de eventos en el tipo base es a la vez:
- un delegado que no sea EventHandler o EventHandler -y--
- los eventos tanto en la clase base como en la clase derivada se inicializan utilizando un método anónimo o un delegado vacío (ya sea en línea o en el constructor).
De posible relevancia: estamos ejecutando Visual Studio 2012 RTM, que se instaló en el lugar de la versión candidata.
El problema es que el compilador de C # genera un delegado estático utilizado para inicializar el delegado de su instancia, que recibe el mismo nombre para Class1 y Class2.
Class1.CS$<>9__CachedAnonymousMethodDelegate1
existe para que lo use el constructor de Class1 para inicializar PropertyCancelled
, mientras que Class2.CS$<>9__CachedAnonymousMethodDelegate1_
existe para que lo use el constructor de Class2 para inicializar SelectionCancelled
.
Es desafortunado que el compilador de C # no incluya algún tipo de registro de ''cosas'' ''generadas automáticamente'' de la clase padre al decidir cómo nombrar ''cosas'' ''generadas automáticamente para una clase'' hija ''. Abre esto en ILDasm y el problema se vuelve inmediatamente obvio. Es bueno saber que has encontrado un trabajo alrededor. La advertencia es completamente razonable de ignorar, dado que no puede tocar a los delegados estáticos de C #, gracias a una denominación que no cumple con C #.