Этот вопрос задается почти каждый день в той или иной форме.
Анализ типа условного оператора начинается с внутри до снаружи , а не снаружи до внутри .Условный оператор не знает , какому типу присваиваются его результаты , а затем приводит к последствиям и альтернативе этим типам .Это делает наоборот;он вырабатывает типы следствия и альтернативы, берет более общий из этих двух типов, а затем проверяет, может ли быть назначен общий тип.
Следствие и альтернатива не содержат информации о том, какой типлямбда должна быть, и поэтому тип условного не может быть выведен.Поэтому нельзя проверить, правильно ли присвоение.
Удовлетворительно подумать, почему язык был разработан таким образом.Предположим, у вас есть перегрузки:
void M(Func<string, int> f) {}
void M(Func<double, double> f) {}
и вызов
M( b ? n=>n.Foo() : n => n.Bar() );
Опишите, как разрешение перегрузки определяет, какая перегрузка M выбрана в мире, где типы выводятся снаружи внутрь.
Теперь рассмотрим вот что:
M( b1 ? (b2 ? n=>n.Foo() : n => n.Bar() ) : (b3 ? n=>n.Blah() : n=>n.Abc()) );
Сложнее, не так ли?Теперь представьте, что Foo, Bar, Blah и Abc сами по себе являются методами, которые принимают функции, а также имеют аргументы с условными операторами, содержащими лямбда-выражения.
Мы не хотим усложнять процесс вывода типов без соответствующего огромного преимущества.и нет такой огромной выгоды для условного оператора.
То, что вы должны сделать в вашем случае, - приведение одного или обоих последствий и альтернативы конкретному типу.