неявный оператор, использующий интерфейсы
-
02-07-2019 - |
Вопрос
У меня есть универсальный класс, для которого я пытаюсь реализовать неявное приведение типов.Хотя в основном это работает, для приведения интерфейса это не сработает.После дальнейшего расследования я обнаружил, что произошла ошибка компилятора:"Определяемое пользователем преобразование из интерфейса", которое применяется.Хотя я понимаю, что в некоторых случаях это должно соблюдаться, то, что я пытаюсь сделать, действительно кажется законным делом.
Вот пример:
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
или тип интерфейса.
и
Пользовательские преобразования запрещены разрешено конвертировать из или в типы интерфейсов.В частности, это ограничение гарантирует, что не будут выполняться определяемые пользователем преобразования при преобразовании в тип интерфейса, и что преобразование в тип интерфейса выполняется успешно, только если преобразуемый объект на самом деле реализует указанное тип интерфейса.