Неявный оператор с использованием интерфейсов
У меня есть общий класс, который я пытаюсь реализовать неявным типом. Хотя он работает в основном, он не будет работать для литья интерфейса. После дальнейшего расследования я обнаружил, что существует ошибка компилятора: "Пользовательское преобразование из интерфейса", которое применяется. Хотя я понимаю, что это должно быть соблюдено в некоторых случаях, то, что я пытаюсь сделать, похоже на законный случай.
Вот пример:
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 допускает неявное литье типов интерфейсов с использованием ковариации.
Ответы
Ответ 1
Причина, по которой вы не можете этого сделать, заключается в том, что в спецификации языка С# она специально запрещена:
Класс или структура допускается объявить преобразование из источника тип S для целевого типа T, при условии, что все из следующих утверждений:
- ...
- Ни S, ни T не являются
object
или интерфейсом.
и
Пользовательские преобразования не являются разрешено конвертировать из или в интерфейс-типа. В частности, это ограничение гарантирует, что нет происходят пользовательские преобразования при преобразовании в тип интерфейса, и что переход на тип интерфейса успешно, только если фактически преобразованный объект реализует указанные Интерфейс типа.
Источник