Roslyn流畅的语法为多行lambda创建表达式树

Ani*_*Ani 13 .net c# metaprogramming expression-trees roslyn

我正在编写一个基于Roslyn的自定义工具,它试图通过在构建时将给定的多行lambda重写为Expression树来消除CS0834.

编辑:目前,我只针对匿名多行lambdas.

例如:

    // Will produce CS0834 if Bar takes Expression<Action<...>>
    Foo.Bar((int x) => { ... });
Run Code Online (Sandbox Code Playgroud)

    Foo.Bar(Expression.Lambda<Action<int>>(
        Expression.Block(
            ...
            ),
        Expression.Parameter(typeof(int))));
Run Code Online (Sandbox Code Playgroud)

这样就可以正确编译了.虽然我可以找出转换给定代码所需的Expression.(blah)语法,但使用Roslyn完成它是另一回事.也许我只是不知道Roslyn Syntax.(blah)API足以翻译这个原始的lambda

    (int index, float[] a, float[] b) =>
    {
        var sum = 0f;
        for (int i = 0; i < index; i++)
            sum += a[i];

        b[index] = sum;
    });
Run Code Online (Sandbox Code Playgroud)

有人可以帮我写Roslyn Syntax.(blah)语法,它会生成一个类似下面的表达式树吗?

    Expression<Action<int, float[], float[]>> action = 
        Expression.Lambda(
            Expression.Block(
                Expression.Assign(sumParameter, Expression.Constant(0)),
                Expression.Loop(...) // The for loop here
                )
            );
Run Code Online (Sandbox Code Playgroud)

一旦我有了一个起点 - 我应该能够弄清楚或者至少开始翻译这个项目中的简单案例.

非常感谢,非常感谢您的帮助.

Kir*_*kov 13

我们有一个名为Quoter的工具,它将为任何C#程序生成语法.*API调用.

您可以在roslynquoter.azurewebsites.net上查看.

如果你弄清楚生成Expression.*调用的逻辑,你可以轻松生成生成它的代码.

更新:该工具现在是开源的!https://github.com/KirillOsenkov/RoslynQuoter