题
public class Foo : IFooBarable {...}
public class Bar : IFooBarable {...}
那么,为什么然后将这个汇编不...
int a = 1;
IFooBarable ting = a == 1 ? new Foo() : new Bar();
但是,这将会...
IFooBarable ting = a == 1 ? new Foo() : new Foo();
IFooBarable ting = a == 1 ? new Bar() : new Bar();
解决方案
在编译器首先尝试计算右边的表达式:
? new Foo() : new Bar();
有这两个因此错误消息之间不存在隐式转换。你可以这样做:
IFooBarable ting = a == 1 ? (IFooBarable)(new Foo()) : (IFooBarable)(new Bar());
其他提示
这是覆盖在C#语言规范的第7.13节。从本质上讲什么杀死这种情况下是必须有类型三元操作数的2个值之间的隐式转换。这种转换是在可变的类型的abscence考虑。
因此,要么Foo
必须转换为Bar
或反之亦然。两者都不是这样发生编译错误。
后者2工作,但因为它们只考虑1种类型(Foo
或Bar
)。因为它们是相同的类型确定的表达式的类型的简单并能正常工作。
只是添加了一点的正确答案张贴在这里:有两种设计准则,导致这种规范。
第一是,我们的原因"从里到外面"。当你说
double x = 2 + y;
我们第一工作的类型x,那么类型的2,那么类型的y,然后的类型(2+y),和最后,我们的工作是否x和(2+y)具有兼容类型。但我们不要使用的类型x在决定什么类型的2,y或2+y。
因为这是一个很好的规则是因为经常类型的"接收"正是我们努力工作:
void M(Foo f) {}
void M(Bar b) {}
...
M(x ? y : z);
什么是我们在这干什么?我们已经作出的种类型的条件表达了做到载的决议,以便确定这是否是要Foo或酒吧。因此,我们不能 使用 事实上,这就是说,要Foo在我们分析的这类有条件的表情!这是一个鸡和蛋的问题。
此规则的例外情况是lambda表达式 做 把他们的类型,从他们的背景。使这一功能正常工作是出奇的复杂;看到我的 博客串 在lambda表达vs匿名方法如果你有兴趣。
第二个因素是,我们从来没有"魔法"一类型的对你。在给一堆的东西从我们必须推断一类,我们总是推断出一种类型,实际上就在我们面前。
在你的实例,分析是这样的:
- 工作的类型的后果
- 工作的类型的可替代
- 找到最好的类型,是兼容的后果和备选
- 确保有一个转型的条件表达的类型的事情是使用条件式。
在第一点上,我们没理由 外-内;我们不要使用事实上,我们知道是什么类型的变我们要为了作出的种类型的表达。但有趣的事情现在是当你有
b ? new Cat() : new Dog()
我们说"类型的条件式是最好的类型在设置{猫,狗}".我们不说"类型的条件式是最好的类型兼容的猫和狗"。这将是哺乳动物,但我们不这样做。相反,我们说"结果已经被什么东西,我们实际上看到的",而这两种选择,既不是明显的胜利者。如果你说的
b ? (Animal) (new Cat()) : new Dog()
然后我们有一个选择之间的动物和狗,动物是明显的胜利者。
现在,请注意,我们实际上做不正确实施的C#规范时,这样做的类型分析。对细节的错误,请参阅我的 文章 上。
由于条件表达式的类型总是从它的两个部分推断出,而不是从可变,其结果是被应用。这个推断只有当类型相同或一个是参照其他兼容工作。在这种情况下,无论是两种类型的参考是到另一个兼容。