NDepend MethodsCallingMe如何工作?

时间:2013-10-01 08:54:55

标签: c# ndepend

嗨,我正在通过NDepend对我的代码进行一些分析。我想从我的代码库中获取调用某种方法的所有方法,并且我发现它不能像我预期的那样工作。

以下是我的观察:

在我的代码中,我有:

1。)接口IMyInterface,方法为Method1

public interface IMyInterface {
    void Method1();
}

2.)实现上述接口的类

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

3.。)在我的程序代码的某处,我有一个方法可以执行以下操作

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

现在,使用NDepend,我会观察以下内容:

我获得了 MyClass.Method1 方法的IMethod实例,例如 method1Info 及其 MethodsCallingMe 属性返回 0 结果。

method1Info.MethodsCallingMe count为0。

如果我为 IMyInterace.Method1 方法获取IMethod实例 MethodsCallingMe 属性返回 1 MethodCaller

我正在寻找一种方法来查找调用某些方法实现的所有方法,无论它调用哪种类型。我无法通过MethodsCallingMe实现这一目标。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分: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进行静态分析,不尝试进行动态分析。因此,即使在变量MethodCaller()的{​​{1}}上下文类型类中可以推断出没有任何歧义,它也不会试图查看实现抽象方法的人。

但是,由于NDepend code query language非常灵活,以下代码查询可以检测您的案例并提供您希望的结果。请注意,可以匹配误报,但这将是一个非常好的调整案例。

instance

具体地说,这看起来像:

enter image description here


作为旁注,能够在没有歧义的情况下推断通过接口引用的对象的类比规则更多例外,因为通常字段和方法参数是通过接口引用的,并且不包含任何关于它们是如何实例化的。


我使用的代码:

// 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 }