Assign a delegate to a function that returns an anonymous type of variable

The code below is valid:

IEnumerable<SomeThing> things = ...; // map type SomeThing to a new anonymous type, resulting in a strongly typed // sequence based on an anon type var newList = things.Select(item => { return new { ID = item.ID, DateUpdatedOrCreated = ((DateTime)(item.DateUpdated ?? item.DateCreated)).ToShortDateString(), Total = item.Part1 + item.Part2 }; }); 

newList now appears in Visual Studio as IEnumerable<'a> and is strongly typed with the anonymous type created in this function. It's so cool.

What I can't do is figure out a way to assign only an lambda expression (not an enumeration) to an implicitly typed variable. Despite the fact that the compiler has no problems with the anonymous type in the context above, if I try (say)

 var func = (SomeThing item)=> { return new { ... }; }; 

I get the error "Unable to assign lambda expression to implicit typed local variable." This seems like a strange compiler limitation; if I don’t miss something, the types are as unambiguous in the second example as in the first in the beginning: both type parameters are well defined.

Is there any way to do this? Since this is an anonymous type, of course, I have no way to use the type to assign it explicitly, so it would seem that I would be stuck in creating a class for the output type if it is not.

Update

Shortly after I met my hilarious answer with John Skeet's answer, I found similar classes to create a dilemma. In case this is not obvious, the same trick can be used to create strongly typed classes using supposed anonymous types.

 class Processor<T,U> { public Processor(Func<T,U> func) { } } // func is a delegate with anon return type created using method in answer below var instance = new Processor(func); // does not compile! Requires type arguments! 

cannot be created directly, but can be created in the same way as the trick below:

 public static Processor<T,U> Create<T,U>(Func<T,U> func) { return new Processor<T,U>(func); } var instance = Processor.Create(func); // all good 
+6
source share
1 answer

You can do this with type inference:

 var func = BuildFunc((SomeThing item) => { return new { ... }; }); ... static Func<TSource, TResult> BuildFunc<TSource, TResult>( Func<TSource, TResult> function) { return function; } 

Note that BuildFunc doesn’t actually do anything - it just provides the method call needed to get the compiler to type in for generic type arguments for Func<,> - it adds Func<,> information you are interested in, basically - this information, which cannot be indicated as part of a variable declaration, without specifying type arguments.

+8
source

Source: https://habr.com/ru/post/915328/


All Articles