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