使用接口的隐式运算符

implicit operator using interfaces

提问人:Michael Meadows 提问时间:9/27/2008 最后编辑:MatthewMartinMichael Meadows 更新时间:3/21/2021 访问量:34028

问:

我有一个泛型类,我正在尝试为其实现隐式类型转换。虽然它主要有效,但它不适用于接口转换。经过进一步调查,我发现存在一个编译器错误:“用户定义的接口转换”适用。虽然我知道这在某些情况下应该强制执行,但我试图做的似乎是一个合法的案例。

下面是一个示例:

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

有谁知道解决方法,或者谁能以令人满意的方式解释为什么我不能隐式地转换为,因为在我的情况下它没有被转换,而只包含在 Foo 中?interfaceReferenceToBarFoo<IBar>

编辑:看起来协方差可能会提供救赎。我们希望 C# 4.0 规范允许使用协方差对接口类型进行隐式强制转换。

C# 泛型编译 器构造 隐式转换

评论


答:

75赞 Adam Hughes 9/27/2008 #1

不能这样做的原因是,它在 C# 语言规范中被明确禁止:

资料来源:ECMA-334 第 15.10.4 节

允许类或结构 声明来自来源的转化 将 S 型转换为目标类型 T 提供的所有 以下情况属实:

  • ...
  • S 和 T 都不是接口类型object

用户定义的转换不是 允许从接口类型转换或转换为接口类型。特别是,这个 限制确保没有 发生用户定义的转换 转换为接口类型时, 并且只有在 实际转换的对象 实现指定的接口类型

评论

2赞 Michael Meadows 9/27/2008
我知道这是规范的一部分,在某些情况下,接口的隐式转换应该是无效的,但总的来说呢?
2赞 Adam Hughes 9/27/2008
我同意你的看法,我不知道为什么他们让它在所有情况下都无效。在这种情况下,您可以在编译时确定强制转换是否(应该)有效。
3赞 Mark 10/7/2010
我认为对隐式接口强制转换的限制与COM互操作的实现方式有关。COM 使用 .NET 自动处理的 QueryInterface。允许隐式接口转换会造成干扰。
6赞 gregsdennis 12/20/2012
@MichaelMeadows,阅读 Adam Houldsworth 和 Eric Lippert 在 C# 4.0 上下文中对我类似问题的回答可能会有所启发。
2赞 Hatchling 2/4/2017
这是否解释了他们为什么在任何地方做出这个决定?