如何获取方法中使用的内部变量名称

5

如何通过反射或者Roslyn API获取类方法中使用的内部变量列表?

例如,在以下代码中:

class C1{
   private int var1;
   public string var2;

   void action1()
    {
       int var3;
       var3=var1*var1;
       var2="Completed";
   }
}

我希望能够在action1()方法中获取使用的变量列表(var3,var1和var2,包括名称和类型)。

其次,我需要确定上述变量中哪些出现在表达式的左侧,也就是它们的值在这个方法中被修改了。

我认为答案可能在使用Roslyn时得到,但我不知道具体如何操作。 谢谢!


5
通过反射是无法获取变量名的。在非调试模式下编译时,变量名将被删除。 - xanatos
3
为了确保,您是想使用源代码*.cs文件还是已编译的程序集*.dll文件? - Andrii Litvinov
而且Roslyn不可用于查看“正在运行”的代码。它是用于分析源代码或生成源代码的。 - xanatos
3
你为什么要这样做呢?这似乎是非常奇怪的事情。 - PJvG
@svick,非常好的观点!在我的情境和分析中,我还不需要处理这样的情况,但肯定在其他情境下是必要的。 - Supernova
显示剩余3条评论
1个回答

6
正如 @xanatos 所提到的,从编译后的程序集中获取此信息是不可能的。您应该使用 Roslyn 完成此任务并访问源代码。本答案解释了如何检索变量https://dev59.com/1X_aa4cB1Zd3GeqP33wM#23543883,而这篇文章可以作为一个很好的起点Getting Started C# Semantic Analysis
阅读后一篇文章,您可以得到以下代码:
using System;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Roslyn
{
    internal class Program
    {
        private static void Main()
        {
            var tree = CSharpSyntaxTree.ParseText(@"
class C1{
   private int var1;
   public string var2;

   void action1()
    {
       int var3;
       var3=var1*var1;
       var2=""Completed"";
   }
}
");
            var root = (CompilationUnitSyntax) tree.GetRoot();
            var variableDeclarations = root.DescendantNodes().OfType<VariableDeclarationSyntax>();

            Console.WriteLine("Declare variables:");

            foreach (var variableDeclaration in variableDeclarations)
                Console.WriteLine(variableDeclaration.Variables.First().Identifier.Value);

            var variableAssignments = root.DescendantNodes().OfType<AssignmentExpressionSyntax>();

            Console.WriteLine("Assign variables:");

            foreach (var variableAssignment in variableAssignments)
                Console.WriteLine($"Left: {variableAssignment.Left}, Right: {variableAssignment.Right}");
        }
    }
}

产生以下输出:
Declare variables:
var1
var2
var3
Assign variables:
Left: var3, Right: var1*var1
Left: var2, Right: "Completed"

请确保安装Microsoft.CodeAnalysis NuGet包。


感谢@Andrii,我已经怀疑到这一点了,例如,我需要使用Roslyn,问题是如何使用。由于API更改等原因,许多Roslyn示例无效。在发布此问题之前,我已经进行了大量搜索。 - Supernova
@Supernova,好的,明白了。我可能会花点时间明天看看能否让它工作。 - Andrii Litvinov
@Supernova,我已经更新了我的答案,并附上了代码示例。 - Andrii Litvinov
它像魔法般奏效@Andrii。非常感谢您的帮助!! - Supernova
有没有可能获取类中每个方法名称下声明的变量列表?或者,获取变量的完全限定名称?目标是找出哪些变量属于哪个方法,然后属于哪个类。 - Supernova
@Supernova,你应该能够通过遍历root做到这一点。尝试使用调试器遍历子节点以查看内部内容。当您找到包含要搜索的变量声明的方法节点时,即可停止查找。 - Andrii Litvinov

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