Вопрос

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

Вот пример:

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?

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

Это было полезно?

Решение

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

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

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

и

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

Источник

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top