Условный вывод типа оператора

Почему компилятор С# не может вывести тип условного выражения в приведенном ниже коде?

class A {}
class B : A {}
class C : A {}

A TestInference ()
{
    return new Random ().Next () == 0 ? new B () : new C ();
}

РЕДАКТИРОВАТЬ: я знаю, как исправить ошибку компилятора (просто приведите B или C к A), мой вопрос: почему компилятор не может понять, что тип A сам по себе?


person miniBill    schedule 19.10.2013    source источник
comment
Просмотрите блоги. msdn.com/b/ericlippert/archive/2006/05/24/ , упомянутый в этом обсуждении SO: stackoverflow.com/questions/14144131/   -  person Steve Howard    schedule 19.10.2013
comment
@Стив, спасибо. Я отмечу это как дубликат того, что вы связали   -  person miniBill    schedule 19.10.2013


Ответы (1)


Из документов:

Либо тип first_expression и second_expression должен быть одинаковым, либо должно существовать неявное преобразование одного типа в другой.

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

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

Рассмотрим следующий случай:

interface D {}
class A {}
class B : A, D {}
class C : A, D {}

var x = condition ? new B() : new C();

Должен ли компилятор сделать x A или D?

person Chris    schedule 19.10.2013
comment
Да, это была моя точка зрения... - person miniBill; 19.10.2013
comment
Думаю, ответ будет заключаться в том, что тогда это дизайнерское решение команды C#. - person Chris; 19.10.2013
comment
на самом деле есть несколько веских причин для того, чтобы этого не делать, как объяснено в первой из ссылок, опубликованных Стивом - нет, веских причин нет, и они там не обсуждаются. Единственная указанная причина: мы не хотим влезать в бизнес... Другие языки, такие как Scala, без проблем выполняют гораздо более обширный вывод типов. - person Jim Balter; 19.10.2013
comment
Я не согласен. B и C в этом случае наследуются от A. Но что, если они оба также реализовали интерфейс IInterface. Должен ли компилятор заставить оператор возвращать A или IInterface? - person Chris; 19.10.2013