我使用的是Visual Studio2013。我正在重做别人留下的一些可怕的代码,这些代码几乎完全使用全局变量,并试图清除它们,以便可以正确封装每个函数,而不会引起超出范围的影响传递给它(或从中返回)。

有什么方法可以轻松地检查整个项目中是否在变量使用范围之外定义的变量?

我知道我可以单击一个变量,SHIFT+F12会为我找到该单个变量的用法,但我想在整个项目中找到所有此类用法,因为问题真的很严重……不只是一两个问题全局变量,我说的是几十种。试图了解该程序的流程及其状态足以使您大量饮酒!

最佳答案

应该有一个已经以树格式执行此操作的工具,但是没有“查找用法”舞蹈似乎没有一个通常的怀疑者拥有它。

因此,这是使用反射API的一种尝试,方法是查找所有成员变量,然后遍历方法并弄清它们是否接触它们。

此时,您基本上正在研究IL,因此,除非您自己想弄清楚解析规则,否则您将要使用诸如Cecil之类的反汇编程序。我正在使用这个deprecated single file implementation cause it's easy。像Roslyn分析仪或JustDecompile插件之类的东西可能是另一条路线,但我在那儿没有经验。

肯定会有一些极端的情况,如果您要查找整个依赖图,则代码会复杂得多-但是对于快速而肮脏的分析,它至少应该为您提供一个概览。

因此,基本上,您可以使用Reflection和IL读取器来从变量->方法创建映射(您也可以采用其他方法,但这可能值(value)不高):

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

我们的结果将是:
state1: Method1 (1), Method2 (1)
state2: Method2 (2)
state3: Method1 (1), Method2 (2)

被“Method1”使用一次,被读取为“state3”,“Method2”使用两次。

关于c# - 如何查找在C#中当前范围之外定义的变量?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31194115/

10-11 22:04
查看更多