Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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}

like image 664
Rodrick Chapman Avatar asked Nov 30 '22 07:11

Rodrick Chapman


1 Answers

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 
);
like image 77
Mark Brackett Avatar answered Dec 05 '22 07:12

Mark Brackett