为什么不向上转换为另一个通用接口的具体类型

Why won't upcast to concrete type of another common interface

为什么不能向上转换为另一个通用接口的不同具体类型。我在 linqpad 中创建了这个示例。现在我可以理解,如果您在两个 类 之间具有不同的属性,向上转换将失败,因为它无法完成对象。但是在这个场景中,我不明白为什么向上转换会失败。

void Main()
{
    ICommon test = new ConcreteA();

    ((ConcreteA)test).a.Dump();

    // this errors with: Unable to cast object of type 'ConcreteA' to type 'ConcreteB'.
    ((ConcreteB)test).a.Dump();
}

public interface ICommon
{
   string a {get; }
}

public class ConcreteA : ICommon
{
    public string a {
        get{ return "Concrete A"; }
    }
}

public class ConcreteB : ICommon
{
    public string a {
        get{ return "Concrete B"; }
    }
}

编译器是否应该能够将其视为从 double 转换为 int,如果 double 对于 int 来说太大,它会抛出异常,但如果可以进行转换,编译器会做吧。为什么编译器不尝试将 ConcreteA 作为 ConcreteB 加载,如果在 ConcreteB 中有它无法弄清楚的额外属性,那么它会抛出。

因为您正在尝试转换为另一个 class,它与支持相同接口的第一个无关。您正在尝试做的是某种 C# 不支持的 Duck 类型。

在您的情况下,您希望直接在接口上调用方法而不进行强制转换,例如:

test.a.Dump()

这就是您使用该界面的首要原因。这是一份class"what capabilities it supports".

的合同

由于 ConcreteAConcreteB 一无所知(在你的情况下,因为它们可能对 属性 a 有不同的实现),我建议你为混凝土 B 像这样:

public class ConcreteA
{
    /* rest of your code ... */

    public static explicit operator ConcreteB(ConcreteA instance)
    {
        // implement converting from ConcreteA to ConcreteB
    }
}

有关显式运算符的更多信息:https://msdn.microsoft.com/en-us/library/xhbhezf4.aspx