Подтвердить что ты не робот

Неявный оператор с использованием интерфейсов

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

Вот пример:

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: Похоже, что ковариация может предложить спасение. Пусть надежда, что спецификация С# 4.0 допускает неявное литье типов интерфейсов с использованием ковариации.

4b9b3361

Ответ 1

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

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

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

и

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

Источник