Как определить реализацию интерфейса по умолчанию в C #? - PullRequest
30 голосов
/ 17 июля 2010

В c # существует некоторый код черной магии, в котором вы можете определить реализацию интерфейса по умолчанию.

Таким образом, вы можете написать

var instance = new ISomeInterface();

Любые указатели?

ОБНОВЛЕНИЕ 1: Обратите внимание, что я не спрашивал, если это хорошая идея.Как это можно было сделать.

ОБНОВЛЕНИЕ 2: любому, кто видит принятый ответ.

  • "это следует рассматривать просто как любопытство."от Marc Gravel Интерфейсы "новичков"
  • "Плохо использовать инструмент, предназначенный для взаимодействия COM, чтобы сделать что-то совершенно иное. Это делает ваш код невозможным для понимания дляследующий парень, который должен поддерживать его "от Эрика Липперта " Обновление "Интерфейсы
  • " Хотя это может сработать, если оно когда-либо будет найдено в производственном коде рациональным кодером, это будетрефакторинг, чтобы вместо этого использовать базовый класс или внедрение зависимостей. "от Стивена Клири в комментарии ниже.

Ответы [ 3 ]

32 голосов
/ 17 июля 2010

Вот чёрная магия:

class Program
{
    static void Main()
    {
        IFoo foo = new IFoo("black magic");
        foo.Bar();
    }
}

[ComImport]
[Guid("C8AEBD72-8CAF-43B0-8507-FAB55C937E8A")]
[CoClass(typeof(FooImpl))]
public interface IFoo
{
    void Bar();
}

public class FooImpl : IFoo
{
    private readonly string _text;
    public FooImpl(string text)
    {
        _text = text;
    }

    public void Bar()
    {
        Console.WriteLine(_text);
    }
}

Обратите внимание, что не только вы можете создать экземпляр интерфейса, но и передать аргументы его конструктору: -)

3 голосов
/ 17 июля 2010

Только если ISomeInterface является классом.

Обновление (для уточнения):

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

На данный момент единственные реализации по умолчанию выполняются с помощью (возможно abstract) базовых классов.

2 голосов
/ 17 июля 2010

Может быть, вы ссылаетесь на инъекцию зависимостей? Где при использовании DI Framework (например, Ninject или Unity) вы можете определить экземпляр по умолчанию для каждого интерфейса, а затем использовать его следующим образом:

(при условии, что у вас есть IWeapon интерфейс и Sword реализует его)

IKernel kernel = new StandardKernel();
kernel.Bind<IWeapon>().To<Sword>();
var weapon = kernel.Get<IWeapon>();

Но Ninject (и большинство других IoC-сред) может делать более умные вещи, например: скажем, у нас есть класс Warrior, который принимает IWeapon в качестве параметра в своем конструкторе. Мы можем получить экземпляр Warrior от Ninject:

var warrior = kernel.Get<Warrior>();

Ninject передаст указанную реализацию IWeapon методу конструктора Warrior и вернет новый экземпляр.

Кроме этого, я не знаю ни одной языковой функции, которая бы позволяла такое поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...