2013-08-06 2 views
17

내 코드에서 모든 재귀 호출을 찾고 싶습니다.C# 코드의 재귀 호출 검색

Visual Studio에서 파일을 열면 편집기의 왼쪽에 "재귀 호출"아이콘이 표시됩니다. enter image description here

이러한 호출에 대한 전체적인 해결책을 조사하고 싶습니다.

Resharper 명령 줄 도구와 VS의 추가 기능 Resharper - Code Inspection을 사용했지만,이 규칙은 해당 규칙 집합에 적용되지 않았습니다. 내가 하나에 관심이 : 난 정말 "재귀 호출"아이콘 :

편집을 각 파일을 열고 그 파란 분을 확인하고 싶지 않아 -

내가 전체 솔루션을 검사 할 수있는 방법이 있나요 레벨 재귀

+0

이 아이콘이 다중 레벨 재귀에 표시되지 않는다는 것을 알고 계십니까? 즉. 메서드 A는 B를 호출하고 B는 A를 호출합니다. –

+0

예, 저는 단 하나 수준의 재귀를 원합니다. –

답변

16

Mono.Cecil으로 수행하십시오.

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"); 
} 

이 출력됩니다에게 직접 자신을 호출하는 방법을 :

여기에 보여주는 간단한 LINQPad 프로그램입니다. 내가 Call 명령어 만 처리 했으므로 여기서 다른 호출 명령어를 올바르게 처리하는 방법이 확실하지 않거나 심지어 인 경우에도이 가능할 수도 있습니다.

경고 : : 단 하나의 명령어 만 처리했기 때문에 이것은 정적으로 컴파일 된 호출에서만 작동합니다.

동일한 메소드로 다시 돌아가는 가상 호출, 인터페이스를 통한 호출은 이에 의해 감지되지 않으며 훨씬 더 고급 코드가 필요합니다.

+2

매력처럼 작동합니다. 감사합니다. –

+1

확실하지 않은 사람을 위해 명확히 설명합니다. 이 작업을 수행하는 데 Mono가 필요하지 않습니다. LinqPad Pro에서 Query Properties 창에 NuGet 패키지 'Install-Package Mono.Cecil'을 추가 할 수 있습니다. 저렴한 스케이트를 들고 무료 버전을 사용하는 경우 다른 임시 프로젝트에 Nuget 패키지를 다운로드 한 다음 쿼리 속성을 사용하여 추가 어셈블리를 쿼리에 추가해야합니다. 그렇지 않으면 ModuleDefinition.ReadModule에 올바른 참조가 작동하지 않습니다. – Junto

+0

https://github.com/jbevain/cecil/releases를 다운로드하여 위 코드로 빌드하고 실행하고 모든 재귀 호출을 나열하십시오. 감사! – Zyo