eid*_*lon 9 c# encapsulation code-analysis global-variables local-variables
我正在使用Visual Studio 2013.我正在修改其他人留下的一些可怕的代码,它们几乎使用了全局变量,并尝试清理它,这样我就可以正确地封装每个函数,而不会造成影响.传入(或从中返回).
有没有办法轻松检查整个项目中是否有在其使用范围之外定义的变量?
我知道我可以点击一个变量,并SHIFT+F12会找到该变量的用法,但我想在整个项目中找到所有这些用法,因为问题真的很糟糕......它不只是一两个全局变量,我说几十个.试图了解这个程序的流程及其状态足以让你大量饮酒!
应该有一个工具已经以树格式执行此操作,但如果没有“查找用法”舞蹈,通常的嫌疑人似乎都没有它。
因此,这里尝试使用 Reflection API,查找所有成员变量,然后检查方法并确定它们是否触及它们。
此时您基本上正在查看 IL,因此除非您想自己计算解析规则,否则您将需要使用像 Cecil 这样的反汇编器。我正在使用这个已弃用的单文件实现,因为它很简单。Roslyn 分析器或 JustDecompile 插件之类的东西是另一种途径,但我没有这方面的经验。
肯定存在边缘情况,如果您正在寻找整个依赖关系图,代码将会复杂得多 - 但对于快速和肮脏的分析,它至少应该让您有一个概述。
所以,基本上你使用 Reflection 加上 IL reader 从变量 -> 方法中创建一个映射(你也可以采用其他方式,但这可能不太有价值):
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我们的结果将是这样的:
state1: Method1 (1), Method2 (1)
state2: Method2 (2)
state3: Method1 (1), Method2 (2)
Run Code Online (Sandbox Code Playgroud)
读作“state3”被“Method1”使用一次,“Method2”使用两次。