13

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

编辑:此时,我只针对匿名多行 lambda。

例如:

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

    Foo.Bar(Expression.Lambda<Action<int>>(
        Expression.Block(
            ...
            ),
        Expression.Parameter(typeof(int))));

这样就可以正确编译。虽然我可以弄清楚转换给定代码所需的 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;
    });

有人可以帮我编写 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
                )
            );

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

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

4

1 回答 1

13

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

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

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

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

于 2012-09-18T23:02:30.530 回答