三元运算符语法选择接口的实现

Elu*_*FTW 14 c# ternary-operator

我想知道为什么这行代码不能编译:

ILogStuff Logger = (_logMode) ? new LogToDisc() : new LogToConsole();
Run Code Online (Sandbox Code Playgroud)

注意这两个类LogToDiscLogToConsole实现ILogStuff,并且_logMode是一个布尔变量.我得到的错误信息是:

错误3:无法确定条件表达式的类型,因为'xxx.LogToDisc'和'xxx.LogToConsole'之间没有隐式转换

但为什么要有一个呢?我错过了什么?

Adi*_*dil 16

三元运算符没有隐式转换.你需要通过三元运算符将返回的对象强制转换为ILogStuff,这在Eric Lippert对三元条件下的隐式转换问题的答案中有很好的解释.

ILogStuff Logger = (_logMode) ? (ILogStuff) new LogToDisc() : (ILogStuff) new LogToConsole();
Run Code Online (Sandbox Code Playgroud)

从C#语言规范的第7.13章开始:

?:运算符的第二个和第三个操作数控制条件表达式的类型.设X和Y是第二个和第三个操作数的类型.然后,

  • 如果X和Y是相同的类型,那么这是条件表达式的类型.
  • 否则,如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型.
  • 否则,如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型.
  • 否则,无法确定表达式类型,并发生编译时错误.


Lee*_*Lee 8

你需要强制转换到界面:

ILogStuff Logger = (_logMode) ? (ILogStuff)new LogToDisc() : new LogToConsole();
Run Code Online (Sandbox Code Playgroud)

规范描述了条件运算符的行为:

7.14条件运算符

?:运算符的第二个和第三个操作数x和y控制条件表达式的类型.

如果x的类型为X,则y的类型为Y.

  • 如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型.
  • 如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型.
  • 否则,无法确定表达式类型,并发生编译时错误.

之间不存在隐式转换LogToDiscLogToConsole沿任一方向的,所以编译失败.如果您将其中一种类型修复ILogStuff为其他类型的隐式转换将存在.