Подтвердить что ты не робот

Обнаружение рекурсивных вызовов в коде С#

Я хочу найти все рекурсивные вызовы в моем коде.

Если я открываю файл в Visual Studio, я получаю значок "Рекурсивный вызов" в левой части редактора. enter image description here

Я хочу проверить полное решение для таких вызовов.

Я использовал инструменты командной строки Resharper и VS-надстройку Resharper - проверка кода без везения, это правило не применяется в их наборе правил.

Есть ли способ, которым я мог бы проверять целое решение - я действительно не хочу открывать каждый файл и проверять этот синий значок "Рекурсивный вызов":)

Изменить: меня интересует одноуровневая рекурсия

4b9b3361

Ответ 1

Вы можете сделать это с помощью Mono.Cecil.

Вот простая LINQPad программа, которая демонстрирует:

const string AssemblyFilePath = @"path\to\assembly.dll";

void Main()
{
    var assembly = ModuleDefinition.ReadModule(AssemblyFilePath);
    var calls =
        (from type in assembly.Types
         from caller in type.Methods
         where caller != null && caller.Body != null
         from instruction in caller.Body.Instructions
         where instruction.OpCode == OpCodes.Call
         let callee = instruction.Operand as MethodReference
         select new { type, caller, callee }).Distinct();

    var directRecursiveCalls =
        from call in calls
        where call.callee == call.caller
        select call.caller;

    foreach (var method in directRecursiveCalls)
        Debug.WriteLine(method.DeclaringType.Namespace + "." + method.DeclaringType.Name + "." + method.Name + " calls itself");
}

Здесь будут выводиться методы, которые вызывают непосредственно. Обратите внимание, что я обработал только инструкцию Call, я не уверен, как правильно обращаться с другими инструкциями по вызову здесь, или даже если это возможно.

Caveat: обратите внимание, что это будет, потому что я обрабатывал только одну команду только для работы со статически скомпилированными вызовами.

Виртуальные вызовы, вызовы через интерфейсы, которые просто возвращаются к тому же методу, не будут обнаружены этим, для этого необходим намного более продвинутый код.

Ответ 2

Это все еще допустимый код для поиска рекурсивных вызовов? Я не могу увидеть метод ReadModule в структуре ModuleDefinition. Пожалуйста, порекомендуйте.