CA1033: Los tipos secundarios deberían poder llamar a los métodos de interfaz
Nombre de tipo |
InterfaceMethodsShouldBeCallableByChildTypes |
Identificador de comprobación |
CA1033 |
Categoría |
Microsoft.Design |
Cambio problemático |
Poco problemático |
Motivo
Un tipo no sellado visible externamente proporciona un método explícito de implementación de una interfaz pública pero no proporciona un método visible externamente alternativo con el mismo nombre.
Descripción de la regla
Tiene en cuenta un tipo base que implementa explícitamente un método de interfaz público.Un tipo que deriva de un tipo base solo puede obtener acceso al método de interfaz heredado a través de una referencia a la instancia actual (this en C#) que se convierte en la interfaz.Si el tipo derivado vuelve a implementar (explícitamente) el método de interfaz heredado, ya no se podrá obtener acceso a la implementación base.La llamada a través de la referencia de la instancia actual invocará la implementación derivada; esto produce recursividad y, finalmente, un desbordamiento de pila.
Esta regla no crea informe sobre la infracción para una implementación explícita de IDisposable.Dispose cuando se proporciona un método Close() o System.IDisposable.Dispose(Boolean) visible externamente.
Cómo corregir infracciones
Para corregir una infracción de esta regla, implemente un método nuevo que exponga la misma funcionalidad y sea visible para tipos derivados o cámbielo a una implementación no explícita.Si se puede realizar un cambio de interrupción, una alternativa es establecer el tipo como sellado.
Cuándo suprimir advertencias
Es seguro suprimir una advertencia de esta regla si se proporciona un método visible externamente que tenga la misma funcionalidad pero con un nombre distinto al del método implementado explícitamente.
Ejemplo
El ejemplo siguiente muestra un tipo, ViolatingBase, que infringe la regla y un tipo, FixedBase, que muestra una corrección de la infracción.
using System;
namespace DesignLibrary
{
public interface ITest
{
void SomeMethod();
}
public class ViolatingBase: ITest
{
void ITest.SomeMethod()
{
// ...
}
}
public class FixedBase: ITest
{
void ITest.SomeMethod()
{
SomeMethod();
}
protected void SomeMethod()
{
// ...
}
}
sealed public class Derived: FixedBase, ITest
{
public void SomeMethod()
{
// The following would cause recursion and a stack overflow.
// ((ITest)this).SomeMethod();
// The following is unavailable if derived from ViolatingBase.
base.SomeMethod();
}
}
}