Тип на самом деле определяется вызывающей стороной , поэтому он входит в сферу действия вызывающей функции - аккуратно избегая вопроса «возврата» анонимного типа.
Это достигается выводом универсального типа. Подпись для Select является Select<Tsource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>
. IEnumerable<TSource>
, очевидно, является исходной коллекцией. В функции преобразования Func<Tsource, TResult>
компилятор может использовать определение типа для объявления анонимного типа.
Другими словами, чтобы передать Func<Tsource, TResult>
в Select
, вы - вызывающая сторона - должны определить TResult
. Это означает, что Select
возвращает не определенный им анонимный тип, а вы.
Чтобы подражать этому, вам просто нужно, чтобы вызывающий определил тип:
TResult ReturnAnonymousType<TResult>(Func<TResult> f) {
return f();
}
Console.WriteLine(ReturnAnonymousType(
() => return new { Text = "Hello World!" } // type defined here, before calling
);