C # и интерфейсы - явные и неявные - PullRequest
10 голосов
/ 25 апреля 2009

В C #, если класс имеет все правильные методы / сигнатуры для интерфейса , но не явно не реализует его как:

class foo : IDoo {}

Может ли класс по-прежнему быть приведен в качестве этого интерфейса?

Ответы [ 5 ]

17 голосов
/ 25 апреля 2009

Duck Typing

То, на что вы ссылаетесь, называется " типизирование утки " (названо в честь идиомы "если оно похоже на утку и крякает как утка, то это должна быть утка") .

В случае утилитарной утечки реализация интерфейса неявна после того, как вы внедрили соответствующие элементы (как вы описываете), однако .NET в настоящее время не имеет широкой поддержки для этого.

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

В то же время вы можете синтезировать типизацию утки с помощью рефлексии с библиотекой, такой как эта , которая позволила бы вам выполнять приведение с утиной типизацией так:

Некоторые мелочи

Интересно, что в C # сегодня есть одно маленькое место, в котором вводится утка - оператор foreach. Кшиштоф Квалина заявляет , что для того, чтобы быть перечисляемым оператором foreach, класс должен:

Предоставить публичный метод GetEnumerator который не принимает параметров и возвращает тип, имеющий два члена: а) метод MoveMext, который не принимает параметров и вернуть логическое значение, и б) свойство Ток с геттером, который возвращает Объект.

Обратите внимание, что он не упоминает ни IEnumerable, ни IEnumerator. Хотя эти интерфейсы обычно реализуются при создании перечислимого класса, если вы отбросили интерфейсы, но оставили реализацию, ваш класс все равно был бы перечислимым на foreach. Вуаля! Duck-типирование! ( Пример кода здесь .)

12 голосов
/ 25 апреля 2009

Нет, это не похоже на Objective-C и некоторые другие языки. Вы должны явно объявить реализацию интерфейса.

4 голосов
/ 25 апреля 2009

При условии, что в IDoo есть участники, этот код не будет компилироваться. Если у IDoo нет участников, тогда да, приведение безопасно (но очевидно ограниченного использования).

3 голосов
/ 25 апреля 2009

Для этого в основном требуется Duck Typing для работы в C #, что не происходит автоматически.

Есть несколько библиотек , которые могут сделать это, однако.

2 голосов
/ 25 апреля 2009
public class A
{
   public void DoSomething();
}

public interface IDoSomething
{
   void DoSomething();
}

public class B : A, IDoSomething
{ }

B удовлетворяет IDoSomething.DoSomething, наследуя от A

...