Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

visual studio - 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. enter image description here

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.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could do it with Mono.Cecil.

Here is a simple LINQPad program that demonstrates:

const string AssemblyFilePath = @"pathoassembly.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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...