Джона, конечно, правильный. Поучительно подумать, почему C# не рассматривает «возвращаемый тип» при выполнении выводов. Основной принцип здесь является то, что информация о типе перетекает из внутри к вне, а не из вне к внутри при анализе выражения.
В вашем конкретном случае совершенно очевидно, что тип предполагаемого типа возврата является тем, что вы назначаете нечто, что однозначно удваивается. Но есть много ситуаций, когда это совершенно не очевидно:
static R M<A, R>(A a) { return default(R); }
static void N(int x, double y) {}
static void N(double x, int y) {}
...
N(M(123), 456);
ОК, что теперь? Если информация о типе «то, что назначается», должна указывать в на вывод типа на M, тогда информация о типе, которая должна протекать, «это может быть int или double».
Но подождите, это правильно? Мы можем сделать более логичные выводы здесь о том, каков должен быть тип возвращаемого типа.
Если это int, то у нас есть N(M<int, int>(123), 456)
, а разрешение перегрузки на N будет терпеть неудачу, потому что этот вызов неоднозначен; это может быть либо версия N!
Следовательно, это не может быть int, не так ли? Он должен быть двойным, потому что тогда это означает, что вызов N(M<int, double>(123), 456)
, который однозначно является второй перегрузкой.
Теперь представьте себе, что для вызова формы Q (R (S (N (M (...с дюжиной перегрузок каждого, и, возможно, с несколькими лямбдами, брошенными туда. Анализ становится безумно сложным; для пользователей становится сложно правильно и сложно понять, что делает их программа, почему она создает ошибки и как их исправлять.
Гораздо проще просто сказать, что анализ типов выражения должен определяться из его содержимого, а не его контекста. Вот что мы делаем. Проблема разрешения перегрузки, которую вы бросаете в компилятор, должна быть разрешима, не рассматривая контекст проблемы; мы рассматриваем только содержимое списка аргументов для решения проблемы, и в списке аргументов недостаточно информации.
Теперь исключение составляют лямбда. Типы параметров Lambda - это, выведенные из их контекста, и в результате вы можете легко заставить компилятор попробовать триллионы возможных назначений типов для глубоко вложенных лямбда, чтобы решить проблему разрешения перегрузки. Но мы не хотим распространять трудности анализа лямбда на весь язык; мы хотим ограничить эти трудности конкретными языковыми особенностями, которые в них нуждаются.
Вы имели в виду вывод? – slaphappy
@kbok Я думаю, что это вмешательство в этот момент: D – user1231231412
Я исправил заголовок. – tomfanning