我有这段代码要解析:
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 月
最佳答案
此解决方案遍历语法树以找到您要查找的内容。备注:
- 它走遍了整棵树。如果你放入更多的类或方法,它只会找到第一个。您可以修改代码以找到任意数量的
for
循环,然后检查每个循环。 - 我已将代码段封装在一个方法中以使其更易于解析。
- 为了便于阅读,我已经分解了每个步骤,您可以折叠它们。
这是源代码,您可以将其转储到控制台应用程序中以运行它。
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/