Can I generate an async method dynamically using S

2019-04-18 07:32发布

问题:

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?

回答1:

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.