1

こんにちは、コードの分析のために NDepend を unsing しています。コードベースから特定のメソッドを呼び出しているすべてのメソッドを取得したかったのですが、期待どおりに機能しないことがわかりました。

ここに私の観察があります:

私のコードには次のものがあります。

1.) メソッド Method1 を持つインターフェイス IMyInterface

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 カウントは 0 です。

IMyInterace.Method1メソッドの IMethod インスタンスを取得すると、MethodsCallingMeプロパティはMethodCallerである1 つのアイテムを返します。

呼び出された型に関係なく、特定のメソッド実装を呼び出しているすべてのメソッドを見つける方法を探しています。MethodsCallingMe ではそれを達成できません。どうすればそれを達成できますか?

4

1 に答える 1

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 コードのクエリ言語は非常に柔軟であるため、次のコード クエリはケースを検出し、希望する結果を提供できます。誤検出は一致する可能性がありますが、かなり微調整されたケースになることに注意してください。

// 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();
        }
    }
}
于 2013-10-01T10:25:07.903 に答える