Roslyn流畅语法用于创建多行lambda表达式的表达式树。

14
我正在编写一个基于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
                )
            );

一旦我有了一个起点,我应该能够找出或者至少开始翻译这个项目中的简单案例。

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

1个回答

14
我们有一个名为 Quoter 的工具,可以为任何 C# 程序生成 Syntax.* API 调用。您可以在 roslynquoter.azurewebsites.net 上实时查看它。如果您找到了生成 Expression.* 调用的逻辑,那么您可以轻松地生成生成代码。更新:该工具现在是开源的!https://github.com/KirillOsenkov/RoslynQuoter

太棒了,谢谢!是的 - 我知道如何根据Roslyn语法树生成相应的表达式树。我使用一个特殊的访问器来遍历语法树,但返回的是表达式而不是语法节点。还有一个相关的问题,我能在我的开源应用程序Brahma(http://brahma.ananthonline.net)中使用Quoter并进行完全归属吗?再次感谢。 - Ani
1
当然可以。Quoter是基于Apache 2.0许可证的,因此您应该可以使用它。 - Kirill Osenkov
1
@ananthonline:你有没有利用这些信息的计划?例如,是否有项目使用Quoter生成Expression.*调用? - Erti-Chris Eelmaa
简而言之:不行。长话短说:我确实编写了一些代码,但从未将其用于发布使用新版本的Brahma。代码生成机制仅适用于VS,这使得代码变得笨重且无法用于其他方面。我决定暂停Brahma直到C#可以生成具有主体的lambda表达式的表达式树。 - Ani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接