如何在C#中找到在当前范围之外定义的变量?

时间:2015-07-02 20:31:07

标签: c# global-variables code-analysis encapsulation local-variables

我正在使用Visual Studio 2013.我正在修改其他人留下的一些可怕的代码,这些代码几乎使用了EXCLUSIVELY全局变量,并尝试清理它,以便我可以正确封装每个函数并且不会导致外部影响传入(或从中返回)的内容。

有没有办法轻松检查整个项目中是否在其使用范围之外定义的变量?

我知道我可以点击一个变量,SHIFT+F12会找到我对该变量的用法,但我想在整个项目中找到所有这些用法,因为问题真的很糟糕..它不只是一两个全局变量,我说几十个。试图了解这个程序的流程及其状态足以让你大量饮酒!

1 个答案:

答案 0 :(得分:1)

应该有一种工具已经以树形式实现了这一点,但是如果没有Find Usages舞蹈,通常没有任何一个嫌疑人可以使用它。

所以,这是尝试使用Reflection API找到所有成员变量,然后查看方法并确定它们是否触及它们。

此时你基本上是在看IL,所以除非你想自己想出解析规则,否则你会想要使用像Cecil这样的反汇编程序。我正在使用这个deprecated single file implementation cause it's easy。像Roslyn分析器或JustDecompile插件这样的东西将是另一条路线,但我没有经验。

肯定存在边缘情况,如果你正在寻找一个完整的依赖图,那么代码将会复杂得多 - 但是对于快速而肮脏的分析,至少应该给你一个概述。

所以,基本上你使用Reflection加上一个IL读者来制作一个变量的地图 - >方法(你也可以走另一条路,但这可能不那么有价值):

while (true)
{
     if (Keyboard.IsKeyDown(Key.A))
     {
           Console.WriteLine("Something");
     }
}

我们的结果将如下:

var variables = typeof(SmallBallOfMud).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
var methods = typeof(SmallBallOfMud).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic);

var d = new Dictionary<string, List<string>>();
foreach (var v in variables) d.Add(v.Name, new List<string>());

// this particular disassembler chokes on externally implemented methods
foreach (var m in methods.Where(m => (m.MethodImplementationFlags | MethodImplAttributes.IL) == 0)) {
    var instructions = MethodBodyReader.GetInstructions(m);

    foreach (var i in instructions) {
        // we'll only check for direct field access here
        var f = i.Operand as FieldInfo; 
        if (f == null) continue;            
        d[f.Name].Add(m.Name);
    }
}
读取为“state3”的

由“Method1”使用一次,“Method2”使用两次。