C# 独立方法ScalingMe是如何工作的?

C# 独立方法ScalingMe是如何工作的?,c#,ndepend,C#,Ndepend,嗨,我正在取消对我的代码的独立分析。我想从我的代码库中获取所有调用特定方法的方法,但我发现它并没有像我预期的那样工作 以下是我的观察结果: 在我的代码中,我有: 一,。与方法Method1的接口IMI接口 public interface IMyInterface { void Method1(); } 二,。实现上述接口的类 public class MyClass : IMyInterface { public void Method1() { // Imp

嗨,我正在取消对我的代码的独立分析。我想从我的代码库中获取所有调用特定方法的方法,但我发现它并没有像我预期的那样工作

以下是我的观察结果:

在我的代码中,我有:

一,。与方法Method1的接口IMI接口

public interface IMyInterface {
    void Method1();
}
二,。实现上述接口的类

public class MyClass : IMyInterface {
    public void Method1() {
        // Implementation
    }
}
三,。在我的程序代码中的某个地方,我有一个方法可以执行以下操作

public void MethodCaller() {
    IMyInterface instance = new MyClass();
    instance.Method1();
}
现在,使用NDepend,我观察到以下几点:

我得到了MyClass.Method1方法的一个IMethod实例,例如method1Info及其 MethodScalingMe属性返回0结果

method1Info.MethodScalingMe计数为0

如果我为IMyInterace.Method1方法MethodScalingMe获取IMethod实例,则MethodCaller属性返回1项,即MethodCaller


我正在寻找一种方法来查找所有调用特定方法实现的方法,无论通过哪种类型调用它。我无法用我的方法实现这一点。我如何才能做到这一点?

事实上,在您的环境中:

from m in Methods where m.IsUsing ("MyNamespace.IMyInterface.Method1()") select m
…返回MyNamespace.CallerClass.MethodCaller并

…不返回任何内容。原因很简单:NDepend进行静态分析,而不尝试进行动态分析。因此,它不会试图寻找谁实现了抽象方法,即使在MethodCaller上下文类型类中,可以推断变量实例,而不会产生任何歧义

然而,由于它非常灵活,下面的代码查询可以检测您的案例并提供您想要的结果。请注意,假阳性可以匹配,但这将是一个非常复杂的情况

// 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 }
具体来说,这看起来像:

作为旁注,能够无歧义地推断通过接口引用的对象的类比规则更为例外,因为字段和方法参数通常通过接口引用,并且不包含关于如何实例化它们的任何信息

我使用的代码是:

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