Как да преброим влагане на ламбда изрази и анонимни методи?

Опитах се да анализирам код и да преброя влагане, но имам проблеми с ламбда израз и анонимни методи. Опитах се да използвам VisitSimpleLambdaExpression() и VisitAnonymousMethodExpression(), но не ми помогна. Кажете ми някой друга идея за преброяване на влагането на ламбда изрази и анонимни методи? Текущият ми код:

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: този пример демонстрира ламбда израз със скоби:

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.");
}

person user3398662    schedule 09.03.2014    source източник
comment
Как точно не работи? Бихте ли предоставили примерен код, заедно с това какво бихте очаквали и какъв всъщност е резултатът?   -  person svick    schedule 09.03.2014
comment
Примерите, които публикувахте и след това бързо изтрихте, не са валиден C# код. Както и да е, ако искате да публикувате код, вероятно е най-добре да редактирате въпроса, вместо да публикувате коментар.   -  person svick    schedule 09.03.2014
comment
кодът на този пример може да не е правилен, тъй като беше написан само за анализиране   -  person user3398662    schedule 09.03.2014


Отговори (1)


Когато посетителят на синтаксиса срещне вид възел, който няма отменен метод 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);
}

Също така ще ви трябва подобен код за всички случаи, когато ламбда може да се появи в друг израз.

Това е причината, поради която моят оригинален NestingLevelVisitor хвърля изключение е DefaultVisit: по този начин можете да откриете видове възли, които не t handle все още и вие сте принудени изрично да посочите как да се справите с тях (вместо да задавате всичко по подразбиране на „връщане на 0“).

person svick    schedule 09.03.2014
comment
Можете ли да ми помогнете как да предефинирам възли, какво ми трябва? - person user3398662; 09.03.2014
comment
Разбрах за анонимните методи, но все още имам проблеми с ламбда израза - person user3398662; 10.03.2014