que polimorfismo polimorfico parametrico metodos herencia form definicion and abstractos c# code-analysis idisposable

c# - polimorfismo - Code Analysis CA1063 se activa cuando deriva de IDisposable y proporciona implementación en la clase base



que es override en c# (3)

Tengo un código que activará el análisis de código de advertencia CA1063:

CA1063: Microsoft.Design: elimine IDisposable de la lista de interfaces implementadas por ''Functionality'' y anule la clase base Dispose implementation en su lugar.

Sin embargo, no estoy seguro de qué debo hacer para corregir esta advertencia.

En resumen, tengo una interfaz IFunctionality que se deriva de IDisposable . La Functionality clase implementa la Functionality IFunctionality pero se deriva de la clase Reusable para poder reutilizar el código som. La clase Reusable también se deriva de IDisposable .

public class Reusable : IDisposable { ~Reusable() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(Boolean disposing) { // ... } public void DoSomething() { // ... } } public interface IFunctionality : IDisposable { void DoSomething(); void DoSomethingElse(); } public class Functionality : Reusable, IFunctionality { public void DoSomethingElse() { // ... } #if WORK_AROUND_CA1063 // Removes CA1063 protected override void Dispose(Boolean disposing) { base.Dispose(disposing); } #endif }

Puedo deshacerme de la advertencia anulando el Dispose on Functionality y llamando a la clase base Dispose aunque hacerlo no debería cambiar la semántica del código.

Entonces, ¿hay algo sobre IDisposable en este contexto que he pasado por alto o es solo CA1063 el que falla para este constructo en particular?

Sé que puedo suprimir CA1063 pero la regla es bastante amplia y no quiero perderme ningún otro problema al implementar IDisposable informado por esta regla.


Esto es un falso positivo debido a un error menor en la regla en sí. Al tratar de averiguar si una clase vuelve a implementar IDisposable (después de descubrir que hay una implementación de clase base que podría ser anulada), solo mira si las interfaces de la clase incluyen IDisposable. Desafortunadamente, la lista de interfaz que aparece en los metadatos del ensamblado incluye la lista de interfaces "explosionadas", incluidas todas las interfaces heredadas mediante interfaces que la clase implementa explícitamente en el código C # original. Esto significa que FxCop está viendo una declaración que se parece a la siguiente para su clase de Funcionalidad:

public class Functionality : Reusable, IFunctionality, IDisposable { ... }

Dada esta representación de metadatos, la regla ImplementIDisposableCorrectly debería ser un poco más inteligente acerca de cómo intenta determinar si la clase está realmente implementando IDisposable (por ejemplo, buscando una implementación Dispose () explícita si la clase base tiene un Disposición anulable (bool)). Sin embargo, dado que la regla no hace esto, su mejor enfoque es suprimir los falsos positivos.

Por cierto, recomendaría seriamente considerar el uso de SuppressMessageAttribute para suprimir los falsos positivos en lugar de su enfoque actual de compilación condicional. p.ej:

[SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "False positive. IDisposable is inherited via IFunctionality. See http://.com/questions/8925925/code-analysis-ca1063-fires-when-deriving-from-idisposable-and-providing-implemen for details.")] public class Functionality : Reusable, IFunctionality { ... }

Además, es posible que desee considerar seriamente deshacerse del finalizador ...


Esto está relacionado con el uso de IDisposable lugar de la interfaz en sí misma. Simplemente está implementando el patrón recomendado para su uso proporcionando y anulando un método Dispose(bool) protegido; esto no es parte de la interfaz en sí.

Si su método de anulación en realidad no agrega nada, entonces no hay problema omitiéndolo. Advertencia CA1063 está ahí para resaltar el problema para usted, pero si sabe que en realidad no hay recursos para eliminar en su caso, puede evitarlo proporcionando la implementación vacía que tiene, o excluyendo esta regla en particular para este particular archivo.

Puede hacer esto con el atributo SuppressMessageAttribute .


Su ''solución alternativa'' es el patrón correcto aquí, para una clase derivada que implemente IDisposable nuevamente.

Pero creo que deberías reconsiderar el diseño de IFunctionality : IDisposable . ¿Ser desechable es realmente una preocupación de IFunctionality ? Creo que esa decisión pertenece a la clase implementadora.