如何计算lambda表达式和匿名方法的嵌套?

时间:2014-03-09 14:45:03

标签: c# roslyn

我试图解析代码并计算嵌套,但我有lambda Expression和匿名方法的问题。我试图使用VisitSimpleLambdaExpression()和VisitAnonymousMethodExpression(),但它没有帮助我。告诉我任何人计算Lambda表达式和匿名方法的嵌套的另一个想法?我目前的代码:

class NestingLevelVisitor : SyntaxVisitor<int>
{
    public override int VisitMethodDeclaration(MethodDeclarationSyntax node)
    {
        return Visit(node.Body);
    }

    public override int VisitBlock(BlockSyntax node)
    {
        if (node.Statements.Select(Visit).Count() == 0)
            return 0;
        return node.Statements.Select(Visit).Max();
    }

    public override int VisitExpressionStatement(ExpressionStatementSyntax node)
    {
        return 0;
    }

    public override int VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node)
    {
        int result = Visit(node.Block);
        return result + 1;  //dont works
    }

    public override int VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
    {
        Console.WriteLine(node.Body);
        int result = Visit(node.Body);
        return result + 1;  //dont works
    }
}

UPD: 此示例演示了带括号的lambda表达式:

class Program
{
    static void Main()
    {
        int m = 0;
        document =>
        {
            return new InsertRequest(nominalType, document);
        };
    }
}

和嵌套= 1

但如果我使用这样的结构:

bool f2()
         {
                int a = 1;
                Func< bool, bool> not = b =>!b;
                return 1;
         }

嵌套没有改变

此方法包含匿名方法并嵌套此方法= 1:

static void Main()
{
    Printer p = delegate(string j)
    {
        System.Console.WriteLine(j);
    };
    p("The delegate using the anonymous method is called.");
    p = new Printer(TestClass.DoWork);
    p("The delegate using the named method is called.");
}

1 个答案:

答案 0 :(得分:2)

当语法访问者遇到没有重写的Visit方法的节点类时,它只返回0.

并且你不会覆盖VisitLocalDeclarationStatement,所以这正是发生的事情,无论该语句中有什么表达式。

在局部声明中处理复杂表达式需要的是:

public override int VisitLocalDeclarationStatement(
    LocalDeclarationStatementSyntax node)
{
    return node.Declaration.Variables.Select(Visit).Max();
}

public override int VisitVariableDeclarator(VariableDeclaratorSyntax node)
{
    if (node.Initializer == null)
        return 0;

    return Visit(node.Initializer.Value);
}

当lambda出现在另一个表达式中时,您还需要类似的代码。

这就是my original NestingLevelVisitor抛出异常DefaultVisit的原因:这样,您可以检测到尚未处理的节点类型,并且您必须明确指定如何处理它们(而不是将所有内容默认为“返回0”)。