我想在我的代码中找到所有递归调用。
如果我在 Visual Studio 中打开文件,我会在编辑器的左侧看到“递归调用”图标。
我想检查此类呼叫的整个解决方案。
我使用了 Resharper 命令行工具和 VS 的插件 Resharper - 没有运气的代码检查,此规则不适用于他们的规则集中。
有什么方法可以检查整个解决方案 - 我真的不想打开每个文件并检查那个蓝色的“递归调用”图标:)
编辑:我对单级递归感兴趣
我想在我的代码中找到所有递归调用。
如果我在 Visual Studio 中打开文件,我会在编辑器的左侧看到“递归调用”图标。
我想检查此类呼叫的整个解决方案。
我使用了 Resharper 命令行工具和 VS 的插件 Resharper - 没有运气的代码检查,此规则不适用于他们的规则集中。
有什么方法可以检查整个解决方案 - 我真的不想打开每个文件并检查那个蓝色的“递归调用”图标:)
编辑:我对单级递归感兴趣
你可以用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");
}
这将输出直接调用自身的方法。请注意,我只处理了调用指令,我不确定如何在这里正确处理其他调用指令,或者即使这是可能的。
警告:请注意,这将因为我只处理那条指令,只适用于静态编译的调用。
虚拟调用,通过接口调用,只是碰巧回到相同的方法,不会被检测到,为此需要更高级的代码。