C#中的三元运算符

时间:2012-03-07 11:17:44

标签: c# .net compiler-errors ternary-operator

有人可以向我解释当你使用三元运算符时幕后会发生什么吗? 做这行代码:

string str = 1 == 1 ? "abc" : "def";

是作为简单的if / else语句生成的吗? 请考虑以下事项:

class A
{
}

class B : A
{
}

class C : A
{
}

现在使用三元表达式如下:

A a1 = 1 == 1 ? new B() : new C();

这甚至没有编译出这个错误:

  

无法确定条件表达式的类型,因为“ConsoleApp1.B”和“ConsoleApp2.C”之间没有隐式转换

有人能说清楚这个吗?

4 个答案:

答案 0 :(得分:8)

条件运算符表达式的类型必须 第二个操作数的类型第三个​​操作数的类型。所以其中一个必须可以转换为另一个。

在你的情况下,他们不能相互转换 - 但都可以转换为第三种类型(A)。编译器不会考虑这一点,但您可以强制它:

A a1 = 1 == 1 ? new B() : (A) new C();

A a1 = 1 == 1 ? (A) new B() : new C();

有关更多详细信息,请参阅C#4规范的第7.14节。

答案 1 :(得分:2)

msdn ?Operator

的摘录
  

如果条件为真,则计算第一个表达式并成为结果;   如果为false,则计算第二个表达式并成为结果。   只评估了两个表达式中的一个。

非常明确。

你的错误也非常明确,你试图将B分配给C ......但是没有可用的强制转换,所以错误......非常简单

答案 2 :(得分:1)

根据是否存在转换,条件运算符将有效地使用第一个表达式的类型 - 并且不考虑基数(否则它将始终转到object允许这样: ? "hello" : 10)。

在这种情况下,编译器是正确的 - 两种类型之间没有转换。添加一个强制转换,但是在第一个 - 并且它将编译 - (A)new B()

答案 3 :(得分:0)

  

非常明确。

     

你的错误也是非常明确的,你正在尝试将B分配给   一个C ...但没有演员表,所以错误......非常简单

根本不相关。

B和C来自A。

表达式是:

A a1 = 1 == 1? new B():new C();

两个表达式都返回从A

派生的类型

只是编译器查看?:运算符的表达式,并不关心变量a1的类型(表达式的左侧)... 这种实施的原因非常有趣......