Тернарный оператор в C # - PullRequest
2 голосов
/ 07 марта 2012

Может ли кто-нибудь объяснить мне, что происходит за кулисами, когда вы используете троичный оператор? делает эту строку кода:

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 ]

8 голосов
/ 07 марта 2012

Тип выражения условного оператора должен быть или тип второго операнда или тип третьего операнда.Так что один из них должен быть конвертируемым в другой.

В вашем случае они не конвертируемы друг в друга - но оба конвертируемы в третий тип (A).Это не учитывается компилятором, но вы можете заставить его:

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

или

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

См. Раздел 7.14 спецификации C # 4 для получения более подробной информации.

2 голосов
/ 07 марта 2012

Выписка из msdn? Оператор

Если условие истинно, первое выражение вычисляется и становится результатом;если false, второе выражение оценивается и становится результатом.Только одно из двух выражений когда-либо оценивается.

Это довольно явно.

И ваша ошибка тоже довольно явная, вы пытаетесь назначить B для C ... Нонет приведений, так что ошибка ... Довольно просто

1 голос
/ 07 марта 2012

Условный оператор будет эффективно использовать тип первого выражения для второго в соответствии с тем, происходит ли преобразование, и не учитывает базы (в противном случае он просто всегда будет переходить к object, что позволяет: ? "hello" : 10).

В этом случае компилятор корректен - нет преобразования между двумя типами. Однако добавьте приведение к первому - и оно скомпилируется - (A)new B().

0 голосов
/ 07 марта 2012

Это довольно явно.

И ваша ошибка тоже довольно явно, вы пытаетесь присвоить B для C ... Но нет преобразования, так что ошибка ... Довольно просто

Не имеет отношения к делу.

B и C получены из A.

Выражение:

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

Оба выражения возвращают тип, производный от A

Просто компилятор смотрит на выражения оператора?: и не волнует, что такоетип переменной a1 (левая часть выражения) ... Причина такой реализации очень интересна ...

...