CA1033: I metodi di interfaccia devono essere richiamabili dai tipi figlio

TypeName

InterfaceMethodsShouldBeCallableByChildTypes

CheckId

CA1033

Category

Microsoft.Design

Breaking Change

Non sostanziale

Causa

Un tipo visibile esternamente non sealed fornisce un'implementazione di metodo esplicita di un'interfaccia pubblica e non fornisce un metodo visibile esternamente alternativo con lo stesso nome.

Descrizione della regola

Si consideri un tipo di base che implementi in modo esplicito un metodo di interfaccia pubblica.Un tipo che deriva dal tipo di base può accedere al metodo di interfaccia ereditata solo tramite un riferimento all'istanza corrente (this in C#) di cui è stato eseguito il cast nell'interfaccia.Se il tipo derivato reimplementa in modo esplicito il metodo di interfaccia ereditata, l'implementazione di base non è più accessibile.La chiamata tramite il riferimento a un'istanza corrente richiamerà l'implementazione derivata causando la ricorsione e un eventuale overflow dello stack.

Questa regola non segnala una violazione per un'implementazione esplicita di IDisposable.Dispose quando viene fornito un metodo visibile esternamente Close() o System.IDisposable.Dispose(Boolean).

Come correggere le violazioni

Per correggere una violazione di questa regola, implementare un nuovo metodo che esponga la stessa funzionalità e sia visibile ai tipi derivati oppure passare a un'implementazione non esplicita.Se è accettabile una modifica sostanziale, come alternativa è possibile rendere il tipo sealed.

Esclusione di avvisi

L'esclusione di un avviso da questa regola è sicura se viene fornito un metodo visibile esternamente con la stessa funzionalità, ma con nome diverso rispetto al metodo implementato in modo esplicito.

Esempio

Nell'esempio riportato di seguito vengono illustrati un tipo ViolatingBase che viola la regola e un tipo FixedBase che mostra una correzione per la violazione.

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();
      }
   }
}

Vedere anche

Riferimenti

Interfacce (Guida per programmatori C#)