7

我想列出从特定方法调用的所有方法。例如,如果我有以下代码:

public void test1() {

   test2();


   test3();
}

该列表应包含 test2() 和 test3()。如果可以列出同一类的方法以及另一个类的方法,那就太好了。

另外,我想找到一种方法来检测方法中使用了哪些字段:

public class A {

   private String test1 = "";
   private String test2 = "";

   public void test() {
      Console.WriteLine(test1);
   }

}

因此应该列出 test1。

我尝试使用 Mono.Cecil 进行此操作,但不幸的是我找不到有关该项目的大量文档。那么有人知道该怎么做吗?

编辑:我想用 Mono.Cecil 来做,因为通过它的 API,我可以直接在我的应用程序中使用结果。如果我使用 Visual Studio 或类似工具中的内置工具,则很难进一步处理结果。

4

3 回答 3

9

我并没有真正与 Cecil 合作过,但是HowTo页面显示了如何枚举类型,您的问题似乎只需要遍历您之后的指令:调用和加载字段。此示例代码似乎可以处理您提到的情况,但可能还有更多,您可能也应该检查其他调用说明。如果你让它递归,确保你跟踪你已经检查过的方法。

static void Main(string[] args)
{
    var module = ModuleDefinition.ReadModule("CecilTest.exe");

    var type = module.Types.First(x => x.Name == "A");
    var method = type.Methods.First(x => x.Name == "test");

    PrintMethods(method);
    PrintFields(method);

    Console.ReadLine();
}

public static void PrintMethods(MethodDefinition method)
{
    Console.WriteLine(method.Name);
    foreach (var instruction in method.Body.Instructions)
    {
        if (instruction.OpCode == OpCodes.Call)
        {
            MethodReference methodCall = instruction.Operand as MethodReference;
            if(methodCall != null)
                Console.WriteLine("\t" + methodCall.Name);
        }
    }
}


public static void PrintFields(MethodDefinition method)
{
    Console.WriteLine(method.Name);
    foreach (var instruction in method.Body.Instructions)
    {
        if (instruction.OpCode == OpCodes.Ldfld)
        {
            FieldReference field = instruction.Operand as FieldReference;
            if (field != null)
                Console.WriteLine("\t" + field.Name);
        }
    }
}
于 2010-11-02T00:14:31.397 回答
1

这不能简单地使用 C# 中的反射 API 来完成。确实,您需要解析原始源代码,这可能不是您正在寻找的解决方案。但例如,这就是 Visual Studio 获取此类信息以进行重构的方式。

您可能会在某个地方分析 IL - 沿着 Reflector 所做的工作,但我认为这将是一项巨大的工作。

于 2010-11-01T23:18:34.977 回答
1

如果您想付费,可以使用.NET Reflector 工具。你也可以看看这个.NET Method Dependencies它变得很棘手,因为你将要进入 IL。第三种可能是在 VS 中使用宏引擎,它确实具有分析代码的功能,CodeElement但我不确定它是否可以进行依赖。

于 2010-11-01T23:19:11.230 回答