我有以下界面:
1
| interface IMyInterface {} |
以及以下两个实现:
1 2 3
| class MyImplementation : IMyInterface {}
class MyOtherImplementation : IMyInterface {} |
鉴于此,将编译以下内容:
1 2 3 4 5 6 7 8 9 10 11
| IMyInterface ReturnImplementation ()
{
if(condition )
{
return new MyImplementation ();
}
else
{
return new MyOtherImplementation ();
}
} |
但这不是:
1 2 3 4
| IMyInterface ReturnImplementation ()
{
return condition ? new MyImplementation () : new MyOtherImplementation ();
} |
问题
为什么?我在假定应该编译时会误解什么?就像速记if指定完全相同的类型一样简单吗?如果是这样,为什么?为什么以这种方式进行限制?
- 编译器会给您什么错误?
-
无法进行隐式转换。但是我不是在要求它转换任何东西,而是在要求它返回一个IMyInterface。
-
我不认为这是重复的。我的两种类型都实现了指定的接口。
-
它有点重复,但与IMO差不多,足以使它值得关闭。
-
@Jon没有编辑问题,我看不到以前的重复目标是什么,但是我认为以接口作为基类的三元表达式可以很好地解释它,关键是"编译器不会检查两者是否共享相同的基类型"。
-
顺便说一句-人们认为编译器应该检查吗?会是一个不错的补充吗?还是像这样是有原因的?感谢您到目前为止的所有回复。
-
@CodeCaster:是的,比以前的更好(它在DateTime?和DBNull.Value之间,希望得到object)。我很高兴能解决这个问题,但希望它能坚持下去,因为这是一种主题,如果您还不知道答案,可能很难找到正确的问题:)
-
@Já'€ê?Má'?á'?:不,我对目前的行为感到非常满意。几乎可以肯定,其他任何事情都将变得更加复杂。可惜的是,条件运算符没有以与new[] { expr1, expr2 }完全相同的方式执行推理,尽管精确地确定它们的不同之处很棘手。 (很有趣的是,我试图在今天早些时候提出一个例子……)
What am I misunderstanding in assuming that it should compile?
您没有阅读规格:)
基本上,条件运算符要求第二个操作数和第三个操作数具有相同的类型,或者从其中一个操作数到另一个操作数进行隐式转换(而不是相反)。换句话说,运算符的总结果类型必须是第二个操作数的类型或第三个操作数的类型。
这就是编译器向您提供有关隐式转换的错误消息的原因-您正在要求编译器尝试将MyImplementation隐式转换为MyOtherImplementation,反之亦然。
在您的情况下,您希望结果类型为IMyInterface-因此您应将其中一个操作数(其中一个或两个)强制转换为该类型:
1
| return condition ? (IMyInterface ) new MyImplementation () : new MyOtherImplementation (); |
到那时,编译器将注意到从MyOtherImplementation到IMyInterface的隐式转换,但反之则没有,请选择IMyInterface作为运算符的整体类型。
- 好的!并没有考虑以这种方式进行转换来明确其应有的类型。我喜欢。