简体   繁体   English

检测 C# 代码中的递归调用

[英]Detect Recursive calls in C# code

I want to find all recursive calls in my code.我想在我的代码中找到所有递归调用。

If I open file in Visual Studio, I get "Recursive call" icon on left side of Editor.如果我在 Visual Studio 中打开文件,我会在编辑器的左侧看到“递归调用”图标。在此处输入图片说明

I want to inspect whole solution for such calls.我想检查此类调用的整个解决方案。

I used Resharper Command Line tools and VS's add-in Resharper - Code Inspection with no luck, this rule is not applied in their ruleset.我使用了 Resharper 命令行工具和 VS 的插件 Resharper - 代码检查,但运气不佳,此规则未应用于他们的规则集中。

Is there any way that i could inspect whole solution - i really don't want to open each file and check for that blue-ish "Recursive call" icon :)有什么方法可以检查整个解决方案 - 我真的不想打开每个文件并检查那个蓝色的“递归调用”图标:)

Edit: I am interested in single-level recursion编辑:我对单级递归感兴趣

You could do it with Mono.Cecil .可以Mono.Cecil做到这一点

Here is a simple LINQPad program that demonstrates:这是一个简单的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");
}

This will output the methods that calls themselves directly.这将输出直接调用自己的方法。 Note that I only processed the Call instruction, I'm not certain how to handle the other call instructions correctly here, or even if that is even possible.请注意,我只处理的呼叫指令,我不能确定如何处理其他调用指令正确位置,或者即使是甚至有可能。

Caveat : Note that this will, because I only handled that single instruction, only work with statically compiled calls.警告:请注意,因为我只处理了那条指令,所以这将只适用于静态编译的调用。

Virtual calls, calls through interfaces, that just happen to go back to the same method, will not be detected by this, a lot more advanced code is necessary for that.虚拟调用,通过接口调用,恰好回到同一个方法,不会被检测到,为此需要更多高级代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM