The type is actually defined by the caller, so it falls within the scope of the calling function - carefully avoiding the problem of returning an anonymous type.
This is achieved by deducing the type of the general type. The signature for Select is Select<Tsource, TResult>(IEnumerable<TSource>, Func<TSource, TResult> . IEnumerable<TSource> is obviously the original collection. The conversion function Func<Tsource, TResult> is where the compiler can use type inference for anonymous type declaration.
In other words, to pass Func<Tsource, TResult> to Select , you - the caller - must define TResult . This means that Select does not return the anonymous type defined by it, but by you.
To emulate this, you just need the caller to define the type:
TResult ReturnAnonymousType<TResult>(Func<TResult> f) { return f(); } Console.WriteLine(ReturnAnonymousType( () => return new { Text = "Hello World!" }
source share