c# - 使用接口(interface)的隐式运算符

标签 c# generics compiler-construction casting implicit-conversion

我有一个通用类,我正在尝试为其实现隐式类型转换。虽然它大部分都有效,但它不适用于界面转换。经过进一步调查,我发现存在编译器错误:适用的“用户定义的接口(interface)转换”。虽然我知道这在某些情况下应该强制执行,但我正在尝试做的事情看起来确实像是一个合法的案例。

这是一个例子:

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 规范允许使用协变隐式转换接口(interface)类型。

最佳答案

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

Source: ECMA-334 Section 15.10.4

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.

关于c# - 使用接口(interface)的隐式运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/143485/

相关文章:

c# - 我收到无法理解的 System.NullReferenceException 错误

java - 具有通用引用的树接口(interface)

c# - 可空结构的 IEqualityComparer

来自 jar 内的 JavaCompiler

c - 编译器什么时候会为x86_64生成C语言的间接跳转?我们可以告诉编译器禁用生成间接跳转吗?

c# - 在 C# 中对包含网格控件的列表框进行排序

c# - 从 sql 存储过程加载和调用 C#(程序集)

c# - 标准 java 类的 .Net 实现

c# - 表示数字的值类型是否共享任何接口(interface)?

c# - 强制 C# 编译器创建未使用的对象实例