2013-10-01 51 views
1

您好我正在解除NDepend對我的代碼進行一些分析。我想從我的代碼庫中調用特定方法的所有方法,並且發現它不能像我期望的那樣工作。NDepend MethodsCallingMe如何工作?

這裏是我的意見:

在我的代碼我有:

1)與方法1方法

public interface IMyInterface { 
    void Method1(); 
} 

2.)一類的接口IMyInterface的實現上述接口

public class MyClass : IMyInterface { 
    public void Method1() { 
     // Implementation 
    } 
} 

3.)在我的程序的代碼中的某處我有一個方法執行以下操作

public void MethodCaller() { 
    IMyInterface instance = new MyClass(); 
    instance.Method1(); 
} 

現在,使用NDepend,我注意以下事項:

我得到了MyClass.Method1方法,例如一個IMethod實例方法1信息及其 方法調用我屬性返回結果。

method1Info.MethodsCallingMe數爲0

如果我得到IMethod實例爲IMyInterace.Method1方法MethodsCallingMe屬性返回項目是MethodCaller

我正在尋找一種方法來查找調用某個方法實現的所有方法,而不管它通過哪種類型調用。我無法通過MethodsCallingMe實現。我怎樣才能做到這一點?

回答

0

事實上,在您的上下文:

from m in Methods where m.IsUsing ("MyNamespace.IMyInterface.Method1()") select m 

...返回MyNamespace.CallerClass.MethodCaller()和...

from m in Methods where m.IsUsing ("MyNamespace.MyClass.Method1()") select m 

...什麼都不返回。原因很簡單:NDepend進行靜態分析,並不嘗試進行動態分析。因此,即使在變量instance的上下文類型類別中,可以推斷出沒有任何不明確性,它並不試圖看看誰實現了抽象方法。

但是由於NDepend code query language非常靈活,下面的代碼查詢可以檢測到您的情況並提供您希望的結果。注意,假陽性可以匹配,但它會是一個相當調整的情況。

// Gather the abstract method 
let mAbstract = Application.Methods.WithFullName("MyNamespace.IMyInterface.Method1()").Single() 

from m in Methods where m.IsUsing(mAbstract) 

// Get ctors called by MethodCaller() 
let ctorsCalled = m.MethodsCalled.Where(mc => mc.IsConstructor) 

// Get classes that implement IMyInterface instantiated by MethodCaller() 
let classesInstantiated = ctorsCalled.ParentTypes().Where(t => t.Implement("MyNamespace.IMyInterface")) 

// Get override of Method1() 'probably' called. 
let overridesCalled = classesInstantiated.ChildMethods().Where(m1 => m1.OverriddensBase.Contains(mAbstract)) 

select new { m, overridesCalled } 

具體這個樣子:

enter image description here


作爲一個側面說明,能夠毫不含糊推斷類通過接口引用的對象是超過了異常規則,因爲經常通過接口引用字段和方法參數,並且不包含任何有關如何實例化的信息。


代碼我使用:

namespace MyNamespace { 
    public interface IMyInterface { 
     void Method1(); 
    } 
    public class MyClass : IMyInterface { 
     public void Method1() { 
      // Implementation 
     } 
    } 
    public class CallerClass { 
     public void MethodCaller() { 
      IMyInterface instance = new MyClass(); 
      instance.Method1(); 
     } 
    } 
}