使用接口的隐式运算符

Posted

技术标签:

【中文标题】使用接口的隐式运算符【英文标题】:implicit operator using interfaces 【发布时间】:2008-09-27 12:02:16 【问题描述】:

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

这是一个例子:

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&lt;IBar&gt;,因为在我的情况下它没有被转换,而只包含在 Foo 中?

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

【问题讨论】:

【参考方案1】:

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

Source: ECMA-334 Section 15.10.4

一个类或结构被允许 从源声明转换 类型 S 到目标类型 T 提供所有 以下是正确的:

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

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

【讨论】:

我知道这是规范的一部分,接口的隐式转换在某些情况下应该是无效的,但总的来说? 我同意你的观点,我不知道他们为什么对所有情况都无效。在这种情况下,您可以在编译时确定强制转换是(应该)有效的。 相信隐式接口转换的限制与COM互操作的实现方式有关。 COM 使用 .NET 自动处理的 QueryInterface。允许隐式接口转换会干扰。 @MichaelMeadows,在 C# 4.0 上下文中阅读 Adam Houldsworth 和 Eric Lippert 在my similar question 上的回复可能会有所启发。 这是否解释了他们为什么在任何地方做出这个决定?

以上是关于使用接口的隐式运算符的主要内容,如果未能解决你的问题,请参考以下文章

为啥Java在使用“加号”运算符时会执行从双精度到整数的隐式类型转换? [复制]

JS:关系运算符的隐式转化

用户定义的隐式转换运算符和重载解析

关系运算符中的隐式转换

JavaScript数据类型的隐式转换

为啥从 <T> 到 <U> 的隐式转换运算符接受 <T?>?