c# - 从循环条件获取 Microsoft Roslyn 的迭代次数

标签 c# roslyn

我有这段代码要解析:

int[] tab1 = { 0, 1, 2, 3, 4 };
for (var i = 0; i < tab1.Length - 1; i++) { };

如何使用 Microsoft Roslyn 获取 tab1.Length - 1(本例中为 4)的准确值?

我可以用这段代码找到表达式 tab1.Length - 1:

var collector = new ForCollector();
foreach (var statement in collector.ForStatements)
{
    Console.WriteLine(statement.Condition.ChildNodes().ElementAt(1));
}

其中 ForCollector 是继承 SyntaxWalker 的类,具有覆盖函数 VisitForStatement 但我不知道如何获取 tab1.Length 的值。我想我必须为此目的使用 SemanticModel。

Roslyn 版本 - 2012 年 9 月

最佳答案

此解决方案遍历语法树以找到您要查找的内容。备注:

  1. 它走遍了整棵树。如果你放入更多的类或方法,它只会找到第一个。您可以修改代码以找到任意数量的 for 循环,然后检查每个循环。
  2. 我已将代码段封装在一个方法中以使其更易于解析。
  3. 为了便于阅读,我已经分解了每个步骤,您可以折叠它们。

这是源代码,您可以将其转储到控制台应用程序中以运行它。

using System.Linq;
using Roslyn.Compilers.CSharp;

// Snip some console app wrapping

var code = @"
    public void FindI()
    {
        int[] tab1 = { 0, 1, 2, 3, 4 };
        for (var i = 0; i < tab1.Length - 1; i++) { };
    }";

        var syntaxTree = SyntaxTree.ParseText(code);

        var forStatement = syntaxTree
            .GetRoot()
            .DescendantNodes()
            .OfType<ForStatementSyntax>()
            .First();

        // Gets the name 'tab1' from the for statement condition
        var conditionMemberName = forStatement
            .DescendantNodes()
            .OfType<MemberAccessExpressionSyntax>()
            .First()
            .GetFirstToken()
            .Value;

        // Finds the first variable: int[] tab1 = { 0, 1, 2, 3, 4 };
        var member = syntaxTree
            .GetRoot()
            .DescendantNodes()
            .OfType<VariableDeclarationSyntax>()
            .First()

        // Finds the variable with the correct name 'tab1'
        var variable = member.Variables.Where(x => x.Identifier.Value == conditionMemberName).Single();

        // Find the initializer: { 0, 1, 2, 3, 4 };
        var initializer = variable.Initializer.Value as InitializerExpressionSyntax;

        // Counds the number of items in the initializer
        var lengthOfInitializers = initializer.Expressions.Count;

关于c# - 从循环条件获取 Microsoft Roslyn 的迭代次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20148722/

相关文章:

c# - 如何防止类在工厂外被实例化

C# 确保随机数的存在

c# - Roslyn - 如何可靠地格式化类的空白

visual-studio-2015 - Roslyn 中的重大更改列表

c# - roslyn 如何在 C# 文档顶部添加 "#define VAR"

c# - 在 Xamarin.Forms 中,如何从项目文件夹中读取 Assets 列表?

c# - 如何在选项卡控制选项卡内嵌套多个组框?

c# - 为什么编码后的 key 不等于原始 key ?

command-line-interface - 可以通过命令行实用程序应用 rosyln 代码修复吗?

c# - Roslyn,通过 hostObject 传递值