Search code examples
c#extension-methodsanonymous-typesanonymous-methods

Methods and Anonymous Types


I know that you cannot return anonymous types from methods but I am wondering how the Select extension method returns an anonymous type. Is it just a compiler trick?

Edit

Suppose L is a List. How does this work?

L.Select(s => new { Name = s })

The return type is IEnumerable<'a> where 'a = new {String Name}


Solution

  • The type is actually defined by the caller, so it's in the scope of the calling function - neatly avoiding the issue of "returning" an anonymous type.

    This is accomplished by generic type inference. The signature for Select is Select<Tsource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>. The IEnumerable<TSource> is, obviously, the source collection. The Func<Tsource, TResult> transformation function is where the compiler can use type inference to declare an anonymous type.

    In other words, in order to pass a Func<Tsource, TResult> to Select, you - the caller - must define TResult. Which means Select isn't returning an anonymous type defined by it - but by you.

    To emulate this, you just have to get the caller to define the type:

    TResult ReturnAnonymousType<TResult>(Func<TResult> f) {
       return f();
    }
    
    Console.WriteLine(ReturnAnonymousType(
       () => return new { Text = "Hello World!" } // type defined here, before calling 
    );