может показаться, что компилятор C # определяет тип лямбды в первом методе x => ToStr(x)
как Func<dynamic, dynamic>
и, следовательно, объявляет тип IEnumerable
, возвращаемый как IEnumerable<dynamic>
.Небольшое изменение x => (string)ToStr(x)
, кажется, исправляет это.
Это наиболее вероятно из-за правил вывода типов - потому что если вы измените строку на это:
return t.Select<dynamic, string>(x => ToStr(x));
Это компилируется без ошибок.
Правило вывода конкретного типа, о котором идет речь, однако я не слишком уверен в этом - однако, если вы возьмете следующий код:
public void foo(dynamic d)
{
var f = this.ToStr(d);
string s = f;
}
А затем наведите курсор на 'f' вВ редакторе вы увидите, что intellisense сообщает тип выражения как «динамический f».Это будет связано с тем, что this.ToStr(d)
является динамическим выражением, независимо от того, известен ли сам метод и его тип возвращаемого значения во время компиляции.
Затем компилятор с радостью назначит string s = f;
, поскольку онвозможность статического анализа типа, который, вероятно, будет f
, потому что в конечном итоге ToStr
всегда возвращает строку.
Вот почему этот первый метод требует приведение или явные параметры типа - потому что компилятор делаетToStr
быть типа dynamic
;потому что в нем есть хотя бы одно динамическое выражение.