Поделиться через


CA1033: методы интерфейса должны быть доступны для вызова дочерним типам

TypeName

InterfaceMethodsShouldBeCallableByChildTypes

CheckId

CA1033

Категория

Microsoft.Design

Критическое изменение

Не критическое

Причина

Незапечатанный тип, доступный для внешнего кода, предоставляет явную реализацию метода открытого интерфейса и не предоставляет доступный для внешнего кода альтернативный метод с тем же именем.

Описание правила

Рассмотрим базовый тип, который явно реализует открытый метод интерфейса. Тип, производный от базового типа, может получить доступ только к наследованным методам интерфейса посредством ссылки на текущий экземпляр (ключевого слова this в C#), приведенный к интерфейсу. Если производный тип повторно (и явно) реализует наследованный метод интерфейса, базовая реализация перестает быть доступной. Вызов посредством ссылки на текущий экземпляр относится к производной реализации; это приводит к рекурсии и возможному переполнению стека.

Данное правило не сообщает о нарушениях для явной реализации метода IDisposable.Dispose, если предоставлен доступный для внешнего кода метод Close() или System.IDisposable.Dispose(Boolean).

Устранение нарушений

Чтобы устранить нарушение данного правила, реализуйте новый метод, который предоставляет те же функциональные возможности и доступен для производных типов. Можно также изменить явную реализацию на неявную. Если допустимы критические изменения, альтернативный способ заключается в запечатывании типа.

Отключение предупреждений

Отключение предупреждений о нарушении данного правила безопасно в том случае, если предоставлен доступный для внешнего кода метод с теми же функциональными возможностями, имя которого отличается от имени явно реализованного метода.

Пример

В следующем примере показан тип ViolatingBase, который нарушает данное правило, и тип FixedBase, демонстрирующий устранение нарушения.

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

См. также

Ссылки

Интерфейсы (Руководство по программированию в C#)