Partager via


CA1033 : Les méthodes d'interface doivent pouvoir être appelées par les types enfants

TypeName

InterfaceMethodsShouldBeCallableByChildTypes

CheckId

CA1033

Catégorie

Microsoft.CSharp

Modification avec rupture

Modification sans rupture

Cause

Un type unsealed visible de l'extérieur fournit une implémentation de méthode explicite d'une interface publique mais ne fournit aucune méthode de substitution visible de l'extérieur de même nom.

Description de la règle

Envisagez un type de base qui implémente explicitement une méthode d'interface publique. Un type qui dérive du type de base peut accéder uniquement à la méthode d'interface héritée par le biais d'une référence à l'instance actuelle (this en C#) dont un cast est réalisé en interface. Si le type dérivé ré-implémente (explicitement) la méthode d'interface héritée, l'implémentation de base n'est plus accessible. L'appel effectué par le biais de la référence d'instance actuelle appelle l'implémentation dérivée ; il en résulte une récursivité et un dépassement de capacité de la pile.

Cette règle ne rapporte pas de violation pour une implémentation explicite de IDisposable.Dispose lorsqu'une méthode Close() ou System.IDisposable.Dispose(Boolean) visible de l'extérieur est fournie.

Comment corriger les violations

Pour corriger une violation de cette règle, implémentez une nouvelle méthode qui expose les mêmes fonctionnalités et qui est visible par les types dérivés, ou changez-la en une implémentation non-explicite. Si une modification avec rupture est acceptable, une solution de substitution consiste à rendre le type sealed (scellé).

Quand supprimer les avertissements

Il est possible de supprimer sans risque un avertissement de cette règle si une méthode visible de l'extérieur est fournie, affichant les mêmes fonctionnalités mais un nom différent de celui de la méthode implémentée explicitement.

Exemple

L'exemple suivant présente un type, ViolatingBase, qui viole la règle et un autre, FixedBase, qui illustre un correctif pour la 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();
      }
   }
}

Voir aussi

Référence

Interfaces (Guide de programmation C#)