С# и интерфейсы - Явные или неявные

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

class foo : IDoo {}

Может ли класс быть включен в этот интерфейс?

Ответ 1

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

Ответ 2

Утиная печать

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

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

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

В то же время вы можете синтезировать утиную печать через отражение, такую ​​библиотеку, как это, что позволит вам делать утиный тип: IDoo myDoo = DuckTyping.Cast<IDoo>(myFoo)

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

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

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

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

Ответ 3

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

Ответ 4

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

Существуют библиотеки, которые могут это сделать.

Ответ 5

public class A
{
   public void DoSomething();
}

public interface IDoSomething
{
   void DoSomething();
}

public class B : A, IDoSomething
{ }

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