неявный оператор с использованием интерфейсов - PullRequest
52 голосов
/ 27 сентября 2008

У меня есть универсальный класс, для которого я пытаюсь реализовать неявное приведение типов. Хотя это в основном работает, оно не будет работать для приведения интерфейса. После дальнейшего изучения я обнаружил, что существует ошибка компилятора: «Определяемое пользователем преобразование из интерфейса». Хотя я понимаю, что в некоторых случаях это должно выполняться, то, что я пытаюсь сделать, кажется вполне законным.

Вот пример:

public class Foo<T> where T : IBar
{
    private readonly T instance;

    public Foo(T instance)
    {
        this.instance = instance;
    }
    public T Instance
    {
        get { return instance; }
    }
    public static implicit operator Foo<T>(T instance)
    {
        return new Foo<T>(instance);
    }
}

Код для его использования:

var concreteReferenceToBar = new ConcreteBar();
IBar intefaceReferenceToBar = concreteReferenceToBar;
Foo<ConcreteBar> concreteFooFromConcreteBar = concreteReferenceToBar;
Foo<IBar> fooFromConcreteBar = concreteReferenceToBar;
Foo<IBar> fooFromInterfaceBar = intefaceReferenceToBar; // doesn't work

Кто-нибудь знает обходной путь, или кто-нибудь может удовлетворительно объяснить, почему я не смог бы неявно привести interfaceReferenceToBar к Foo<IBar>, поскольку в моем случае он не конвертируется, а содержится только внутри Foo

EDIT: Похоже, ковариация может предложить спасение. Будем надеяться, что спецификация C # 4.0 допускает неявное приведение типов интерфейса с использованием ковариации.

1 Ответ

56 голосов
/ 27 сентября 2008

Причина, по которой вы не можете этого сделать, заключается в том, что это специально запрещено в спецификации языка C #:

Класс или структура могут объявить конверсию из источника тип S для целевого типа T при условии, что все верно следующее:

  • ...
  • Ни S, ни T не являются object или тип интерфейса .

и

Пользовательские преобразования не являются разрешено конвертировать из или в интерфейс-типа . В частности, это ограничение гарантирует, что нет пользовательские преобразования происходят при преобразовании в интерфейс типа , и что преобразование в interface-type успешно, только если объект конвертируется на самом деле реализует указанное интерфейс типа .

Источник

...