Los tipos secundarios deberían poder llamar a los métodos

Actualización: noviembre 2007

Nombre de tipo

InterfaceMethodsShouldBeCallableByChildTypes

Identificador de comprobación

CA1033

Categoría

Microsoft.Design

Cambio problemático

No 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 sólo 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();
      }
   }
}

Vea también

Referencia

Interfaces (Guía de programación de C#)