2013-10-01 2 views
1

Привет, я не знаю NDepend для некоторого анализа моего кода. Я хотел получить все методы из моей кодовой базы, которые вызывают определенный метод, и я заметил, что он не работает так, как я ожидал.Как работает NDepend MethodsCallingMe?

Вот мои наблюдения:

В моем коде у меня есть:

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, я наблюдаю следующее:

я получить экземпляр IMethod для метода MyClass.Method1, например, method1Info и его MethodsCallingMe Возврат недвижимости результат.

Количество method1Info.MethodsCallingMe 0.

Если я получаю IMethod экземпляр для метода IMyInterace.Method1 MethodsCallingMe свойство возвращает элемент, который MethodCaller.

Я ищу способ найти все методы, которые вызывают реализацию определенного метода независимо от того, через какой тип он вызывается. Я не могу этого добиться с помощью метода MethodCallingMe. Как я могу это достичь?

ответ

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() тип контекста переменной 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(); 
     } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^