How to determine which methods are called in a method?

前端 未结 3 1981
长情又很酷
长情又很酷 2020-12-31 22:08

I\'d like to list all the methods that are called from a specific method. E.g. if I have the following code:

public void test1() {

   test2();


   test3();         


        
相关标签:
3条回答
  • 2020-12-31 22:34

    you can use .NET Reflector tool if you want to pay. you could also take a look at this .NET Method Dependencies it gets tricky though, as you're going to be going into the IL. A third possible would be to use the macro engine in VS, it does have a facility to analyze code,CodeElement, I'm not sure if it can do dependencies though.

    0 讨论(0)
  • 2020-12-31 22:45

    This can't be done simply using the reflection API within C#. Really you would need to parse the original source code which is probably not the kind of solution you're looking for. But for example this is how Visual Studio gets this kind of info to do refactoring.

    You might get somewhere analysing the IL - along the lines of what Reflector does but that would be a huge piece of work I think.

    0 讨论(0)
  • 2020-12-31 22:58

    I haven't really worked with Cecil but the HowTo page shows how to enumerate the types, your problem only seems to require looping over the instructions for the ones your after: Call and Load Field. This sample code seems to handle the cases you mentioned but there may be more to it, you should probably check the other Call instructions too. If you make it recursive make sure you keep track of the methods you've already checked.

    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);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题