Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I generate an async method dynamically using System.Linq.Expressions?

I know the compiler can't convert an async lambda expression to an expression tree, but is it possible to generate the expression tree manually ?

var expr = Expression.Lambda<Func<Task>>(
     // how do I use 'await' in the body here?
);
var func = expr.Compile();

I can't find any method related to async or await in the Expression class, but perhaps there's another way?

like image 566
Thomas Levesque Avatar asked Jun 16 '14 09:06

Thomas Levesque


People also ask

What is System LINQ expression?

Expression. Provides the base class from which the classes that represent expression tree nodes are derived. It also contains static ( Shared in Visual Basic) factory methods to create the various node types. This is an abstract class.

What is ExpressionVisitor?

The ExpressionVisitor enables the visitor pattern for Expression 's.

Which is a link expression?

LINQ introduced the new type called Expression that represents strongly typed lambda expression. It means lambda expression can also be assigned to Expression<TDelegate> type. The . NET compiler converts the lambda expression which is assigned to Expression<TDelegate> into an Expression tree instead of executable code.


1 Answers

await involves significant compiler re-writing; the generated IL is quite dissimilar to the original C#, with variable hoisting (onto a class) and branching, tasks, continuations, etc. It certainly isn't something that can be represented in a simple lambda, although in recent versions of .NET with richer Expression support (Expression.Block etc), technically I suppose it is probably possible to mimic most of the things the compiler does for await - but you'd probably go quite loopy trying to do it by hand.

No, AFAIK, no facility to automate this translation exists in the Expression API, and frankly I wouldn't ever expect there to be.

The same probably could be say of ILGenerator; frankly, AFAIK the only "easy" way (and I use the word "easy" quite incorrectly) to use await in meta-programming would be to generate C# and run it through roslyn or CSharpCodeProvider.

like image 171
Marc Gravell Avatar answered Oct 03 '22 15:10

Marc Gravell