2010-07-20 1 views
3

VisualStudio를 사용하는 익숙한 문제는 속성 가져 오기 도구를 신비하게 호출하는 것입니다. 이들에 부작용이있는 경우 (가장 일반적인 형태는 if (foo == null) foo = new foo(); return foo;) 디버거의 지역 및 조사 윈도우가 속성을 호출한다는 사실은 디버깅 할 때 예상치 못한 결과를 초래할 수 있습니다. 단지NDepend를 사용하여 어떤 속성 게터에 부작용이 있는지 어떻게 알 수 있습니까?

 [DebuggerBrowsable(DebuggerBrowsableState.Never)] 

그래서 어떻게 큰 코드베이스에서 부작용이있을 수 있습니다 게터를 찾을 수있는 속성을 가진 속성을 태그 :

이에 대한 간단한 해결책이있다?

  SELECT METHODS FROM ASSEMBLIES "FOO" 
     WHERE IsPropertyGetter AND ChangesObjectState 

이 단지 발견을 : 나는 예를 들어, 직접 포함 된 인스턴스의 상태를 변경하는 모든 호텔을 찾을 수는 CQL 언어를 사용하여 :

NDepend

는 이런 종류의 일에 대한 선택의 도구입니다 필드를 직접 변경하는 getter : 간접적으로 변경하는 항목을 어떻게 찾을 수 있습니까? Initialize() 방법으로 전화 하시겠습니까?

답변

1

조엘. Code Query through LINQ capabilities (CQLinq) 덕분에 가능합니다. 다음은 속성 게터에 대한 깊은 변경 가능성을 감지하는 CQLinq 쿼리입니다. 가변성을 유발하는 각 getter에 대해 코드 쿼리는 할당 된 필드 집합을 표시합니다.

// Restrict the iteration only on property getters 
// that are changing states or that call a method that changes state 
let propertyGetters = Application.Methods.Where(m => m.IsPropertyGetter) 

let methodsThatChangeState = 
    Application.Methods.Where(m => m.ChangesObjectState || m.ChangesTypeState) 

from m in propertyGetters.DepthOfIsUsingAny(methodsThatChangeState).DefinitionDomain 
      .Union(propertyGetters.Intersect(methodsThatChangeState)) 

// Find all methods called directly or indirectly by the property getter 
let methodsCalledIndirectly = 
     m.MethodsCalled.FillIterative(
      methods => methods.SelectMany(m1 => m1.MethodsCalled)) 
     .DefinitionDomain 
     .Union(m.ToEnumerable()) 

// Gather all field assigned that are not generated by the compiler 
let fieldsAssigned = methodsCalledIndirectly 
        .SelectMany(m1 => m1.FieldsAssigned) 
        .Where(f => !f.IsGeneratedByCompiler) 

where fieldsAssigned.Any() 
orderby fieldsAssigned.Count() descending 
select new { m, fieldsAssigned } 

이 쿼리는 내가 먼저 자체가 상태를 변경하거나, 직접 또는 간접적으로 상태 (DepthOfIsUsingAny()에 전화)을 변경하는 방법을 를 호출 만 게터를 유지하기 위해, 그것을 최적화 주로하기 때문에 복잡하다.

그런 다음이 게터 각각에 대해 (FillIterative()을 호출하여) 직접 또는 간접적으로 호출되는 모든 메소드 세트를 빌드하고이 메소드로 할당 된 모든 필드를 수집합니다.

enter image description here

+0

감사 패트릭 :

는 구체적으로 질의 결과는 같습니다. 덧붙여 말하자면, CQL을 사용하여 메소드가 인터페이스를 통해 잠재적으로 사용되는지 여부를 확인할 수 있습니까? –

+0

Joel, CQLinq 덕분에 모든 것이 가능해졌습니다. (새로운 대답을보십시오) 다른 필요가 있다면 새로운 질문을하십시오. –

+0

환상적인, 좋은 일을 계속! –

관련 문제