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

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

Вот пример:

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 допускает неявное приведение типов интерфейса с использованием ковариации.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
60
0
25 328
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина, по которой вы не можете этого сделать, заключается в том, что это специально запрещено спецификацией языка 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 object or 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.

Источник

Я понимаю, что это часть спецификации, неявное приведение интерфейса в некоторых случаях должно быть недопустимым, но во всех?

Michael Meadows 27.09.2008 16:59

Я согласен с вами, я не знаю, почему они сделали его недействительным для всех случаев. В этом случае вы можете определить во время компиляции, что приведение является (должно быть) действительным.

Adam Hughes 27.09.2008 17:41

Я полагать, что ограничение на неявное приведение интерфейса связано с тем, как реализовано взаимодействие COM. COM использует QueryInterface, который .NET обрабатывает автоматически. Разрешение неявного преобразования интерфейса может помешать.

Mark 07.10.2010 17:48

@MichaelMeadows, возможно, вам будет интересно прочитать ответы Адама Хулдсворта и Эрика Липперта на мой аналогичный вопрос в контексте C# 4.0.

gregsdennis 19.12.2012 22:15

Объясняет ли это, почему они где-то приняли такое решение?

Hatchling 04.02.2017 04:58

Другие вопросы по теме