У меня есть общий класс, для которого я пытаюсь реализовать неявное приведение типов. Хотя в основном это работает, для кастинга интерфейсов это не сработает. В ходе дальнейшего расследования я обнаружил, что имеется ошибка компилятора: "Пользовательское преобразование из интерфейса", которое применимо. Хотя я понимаю, что в некоторых случаях это должно соблюдаться, то, что я пытаюсь сделать, действительно кажется законным.
Вот пример:
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#:
A class or struct is permitted to declare a conversion from a source type S to a target type T provided all of the following are true:
- ...
- Neither S nor T is
objector an interface-type.
и
User-defined conversions are not allowed to convert from or to interface-types. In particular, this restriction ensures that no user-defined transformations occur when converting to an interface-type, and that a conversion to an interface-type succeeds only if the object being converted actually implements the specified interface-type.
Я согласен с вами, я не знаю, почему они сделали его недействительным для всех случаев. В этом случае вы можете определить во время компиляции, что приведение является (должно быть) действительным.
Я полагать, что ограничение на неявное приведение интерфейса связано с тем, как реализовано взаимодействие COM. COM использует QueryInterface, который .NET обрабатывает автоматически. Разрешение неявного преобразования интерфейса может помешать.
@MichaelMeadows, возможно, вам будет интересно прочитать ответы Адама Хулдсворта и Эрика Липперта на мой аналогичный вопрос в контексте C# 4.0.
Объясняет ли это, почему они где-то приняли такое решение?
Я понимаю, что это часть спецификации, неявное приведение интерфейса в некоторых случаях должно быть недопустимым, но во всех?