2010-11-01 2 views
7

Я хотел бы перечислить все методы, вызываемые по определенному методу. Например. если у меня есть следующий код:Как определить, какие методы вызывают в методе?

public void test1() { 

    test2(); 


    test3(); 
} 

Список должен содержать test2() и test3(). Было бы здорово, если бы были перечислены методы того же класса, но также методы другого класса.

Additionaly Я хотел бы найти способ, чтобы определить, какие поля используются метода:

public class A { 

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

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

} 

РЕКОМЕНДУЕМЫМ поэтому список test1.

Я пробовал это с помощью Mono.Cecil, но, к сожалению, я не смог найти много документации о проекте. Так кто-нибудь знает, как это сделать?

Редактировать: Я хотел бы сделать это с помощью Mono.Cecil, потому что над его API я могу напрямую использовать результаты в своем приложении. Если я использую встроенные инструменты в Visual Studio или аналогичные, довольно сложно ускорить обработку результатов.

ответ

1

Это невозможно сделать, просто используя API отражения в C#. На самом деле вам нужно проанализировать исходный код, который, вероятно, не является тем решением, которое вы ищете. Но, например, Visual Studio получает такую ​​информацию для рефакторинга.

Возможно, вы можете где-то анализировать ИЛ - по тому, что делает Рефлектор, но это будет огромная работа, я думаю.

+0

Да, я уже пробовал это с API отражения, и это было не так просто. Поэтому я попытался использовать Mono.Cecil, потому что я хотел бы использовать результаты расчета в своем коде. (см. мое редактирование) – RoflcoptrException

+0

А! Я не знаком с Mono.Cecil - но это выглядит очень интересно. Если вы готовы заразиться руками с IL, тогда это должно быть возможно, но, к сожалению, я не могу помочь - удачи. –

1

вы можете использовать .NET Reflector tool если вы хотите оплатить. вы можете также взглянуть на это .NET Method Dependencies, но это становится сложно, так как вы собираетесь отправиться в ИЛ. Третьим возможным было бы использовать макрокоманд в VS, у него есть возможность анализировать код, CodeElement, но я не уверен, что он может делать зависимости.

+0

Я хотел бы использовать технику/библиотеку, так как я хотел бы использовать результаты расчета непосредственно в своем приложении. (см. мое редактирование) – RoflcoptrException

+0

Редактировать: Теперь я вижу, инструмент Reflector также имеет API, это выглядит довольно удивительным. Я думаю, что он должен решить хотя бы часть проблемы. – RoflcoptrException

7

Я действительно не работал с Cecil, но на странице HowTo показано, как перечислять типы, ваша проблема, по-видимому, требует зацикливания над инструкциями для тех, которые вы после: Call и Load Field. Этот пример кода, похоже, обрабатывает случаи, о которых вы упомянули, но может быть и больше, вероятно, вы также должны проверить другие инструкции по вызову. Если вы сделаете рекурсию, убедитесь, что вы отслеживаете методы, которые вы уже проверили.

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

Большое спасибо. Я уже пробовал аналогичный подход вчера, но моя проблема в том, что ModuleDefinition.ReadModule («test.dll»); не работает. Всегда есть ошибка, что ModuleDefinition не содержит метод ReadModule (String) – RoflcoptrException

+0

@Roflcoptr, тогда вы просто не используете правильную версию Cecil. Получите его от http://github.com/jbevain/cecil и код, который будет опубликован Kris. –

+0

@ Roflcoptr вы получили это, чтобы работать? – Mario

 Смежные вопросы

  • Нет связанных вопросов^_^