【问题标题】:How to find variables defined outside current scope in C#?如何在 C# 中查找当前范围之外定义的变量?
【发布时间】:2015-07-02 20:31:07
【问题描述】:

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

有什么方法可以轻松地检查整个项目中定义的变量是否超出了它们的使用范围?

我知道我可以点击一个变量,SHIFT+F12 会为我找到该单个变量的用法,但我想在整个项目中找到所有此类用法,因为问题真的很糟糕......不仅仅是一两个全局变量,我说的是几十个。试图了解这个程序的流程和它的状态,足以让你喝得酩酊大醉!

【问题讨论】:

  • R# 可能会对您有所帮助。不确定是否有内置功能。 @MarkBrackett,OP 正在谈论不必是成员变量的成员变量,因为它们只在一种方法中使用。
  • 我得研究一下 R#。
  • @MarkBrackett 如果类成员变量仅用于在类中的两个方法之间传递状态,并且足够私有,则可以将其重构为方法参数。这就是 OP 正在寻找的东西。无需反思; OP 不是在谈论运行时,而是在谈论编译时或设计时。
  • 也许开始第二个解决方案,并在单个类中复制,然后你会在任何超出范围成员的地方得到红色的波浪线。
  • 您可以编写一个小实用程序,使用 Roslyn 查找此反模式的所有实例。在代码中实现重构可能不值得,但编写一些东西只是为了找到仅在一种方法中引用的成员变量应该不难。

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


【解决方案1】:

应该有一个工具已经以树格式执行此操作,但如果没有 Find Usages 舞蹈,通常的嫌疑人似乎都没有它。

因此,这里尝试使用反射 API,通过查找所有成员变量,然后检查方法并确定它们是否触及它们。

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

肯定会有边缘情况,如果您正在寻找完整的依赖关系图,代码会复杂得多 - 但对于快速而肮脏的分析,它至少应该让您有一个概览。

所以,基本上你使用反射加上一个 IL 阅读器从变量 -> 方法制作地图(你也可以采用其他方式,但这可能价值较低):

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)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多