Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
| TypeName | InterfaceMethodsShouldBeCallableByChildTypes | 
| CheckId | CA1033 | 
| Category | Microsoft.Design | 
| Breaking Change | Non-breaking | 
Cause
An unsealed externally visible type provides an explicit method implementation of a public interface and does not provide an alternative externally visible method that has the same name.
Rule Description
Consider a base type that explicitly implements a public interface method. A type that derives from the base type can access the inherited interface method only through a reference to the current instance (this in C#) that is cast to the interface. If the derived type re-implements (explicitly) the inherited interface method, the base implementation can no longer be accessed. The call through the current instance reference will invoke the derived implementation; this causes recursion and an eventual stack overflow.
This rule does not report a violation for an explicit implementation of IDisposable.Dispose when an externally visible Close() or System.IDisposable.Dispose(Boolean) method is provided.
How to Fix Violations
To fix a violation of this rule, implement a new method that exposes the same functionality and is visible to derived types or change to a nonexplicit implementation. If a breaking change is acceptable, an alternative is to make the type sealed.
When to Suppress Warnings
It is safe to suppress a warning from this rule if an externally visible method is provided that has the same functionality but a different name than the explicitly implemented method.
Example
The following example shows a type, ViolatingBase, that violates the rule and a type, FixedBase, that shows a fix for the violation.
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();
      }
   }
}