2012-11-26 12 views
7

System.Reflection.MethodInfoがクラスの実装であるIDisposable.Disposeを参照しているかどうかを確認するためのより正式な/フェイルセーフの方法はありますか?メソッドがIDisposable.Disposeを実装していることを確認してください。

System.Reflection.MethodInfo methodInfo; 
methodInfo = ...; //methodInfo obtaining code here 
bool isDisposeMethod = methodInfo.Name == "Dispose"; 

IはすでにクラスがIDisposableを実装し、したがって、Disposeが存在し、私はDisposeが(他のクラスの方法と比較して)呼び出されたときに特殊な機能を実行すべきであるPostSharpの態様を使用していることを知っています。

+1

クラスが 'IDisposable'を実装している場合、そのクラスが' Dispose'を実装していることが保証されています - それがインターフェイスのポイントです。 – Blorgbeard

+0

私はそれを理解しています。私は 'Dispose'が存在することを知っていますが、PostSharpのアスペクトを使用しています。これは、別の関数と比較して' Dispose'が呼び出されたときに特別な機能を実行する必要があります。 PostSharpアスペクトはメソッドシグネチャを 'System.Reflection.MethodInfo'に返します。 –

答えて

6

持つ:

class DisposableObject : IDisposable 
{ 
    public void Dispose() 
    { 
     //... 
    } 
} 

はあなたが行うことができます。

Type t = typeof(DisposableObject); 

InterfaceMapping m = t.GetInterfaceMap(typeof(IDisposable)); 
MethodInfo mi = t.GetMethod("Dispose"); 

Console.WriteLine(mi == m.TargetMethods[0]); //true 

だから、私は(単にGetMethod(string)を通じて、ここmi)あなたのクラスでいくつかDispose方法についてMethodInfoを持っていると仮定します。次に、宣言タイプ(DisposableObject)〜Type.GetInterfaceMap MethodIDisposable実装のInterfaceMapping Structureオブジェクトを取得する必要があります。そこで、実際にインターフェイスを実装するメソッドを参照するTargetMethodsがあります。したがって、参照がm.TargetMethods[0]に等しいかどうかを確認する必要があるのは、IDisposableが1つのメソッドしか宣言していないためです。 MSDNから

InterfaceMapping構造

そのインタフェースを実装 クラスの実際のメソッドへのインタフェースのマッピングを取得します。

タイプ インタフェース、または場合種類が同じ名前の 方法を持っている複数のインターフェイスを実装することにより、指定されたもの以外のメソッド名を使用するインタフェース メソッドを実装するときInterfaceMapping構造を使用。

InterfaceMapping構造体を取得するには、Type.GetInterfaceMap メソッドを使用します。


一つの発言:あなたのクラスは、明示的にIDisposableを実装することができれば、その後、m.TargetMethods[0]は、明示的な実装を参照します。だから、InterfaceMappingUse Reflection to find Methods that implement explicit interfaces参照)を除いて、それを得る方法があるかどうかはわかりません。MethodInfoこの状況は、エラーを起こしやすい可能性があります。あなたの特定の問題をチェックしてください。

+0

あなたの答えをありがとう。私はオブジェクトが 'IDisposable'を実装しているかどうかをチェックしようとしていません - それは' bool test = myObj is IDispoable'です - 特定の 'MethodInfo'が' IDisposable.Dispose'のクラスの実装を参照しているかどうかをテストしようとしています。 。 –

+0

@ファビアン私は私の答えを編集しました、それを確認してください – horgh

+0

それはおかげで、それは素晴らしいです! –

4

私は正しい方法はGetInterface("IDisposable")にタイプして、インターフェイスオブジェクトに基づいてメソッド情報を取得すると思います。手元のメソッドとインタフェースから返されたメソッドを比較できるはずです。インターフェースはexplcitly実装することができ、同じ名前を持つ他の方法が異なる引数

  • があるかもしれません
    • として名前だけをチェック

      は十分ではありません。ここで

    両方の問題を示していたクラスです。

    class Test : IDisposable 
    { 
        public void Dispose(){} 
        public void Dispose(bool flag){} 
        void IDisposable.Dispose(){} 
    } 
    
  • 3

    私はこれがあなたの場合、そのないきれいなコードで働くかもしれませんが、あなたの方法の情報がIDisposibleクラスから来る場合、それが返すと思います。

    System.Reflection.MethodInfo methodInfo; 
    methodInfo = ...; //methodInfo obtaining code here 
    bool isDisposible = methodInfo.DeclaringType.FindInterfaces(new System.Reflection.TypeFilter((type, filter) => { return type.ToString() == filter.ToString(); }), "System.IDisposable").Any(); 
    

    これがあなたの後のものかどうかはわかりません。

    +0

    これは素晴らしい答えです。私はあなたとコンスタンティン・ヴァシルコフの両方がまとめたものをまとめました: 'bool isDisposible = methodInfo.DeclaringType.GetInterfaceMap(typeof(IDisposable))。TargetMethods.Where(x => x == methodInfo).Any(); ' –

    +2

    上記のメソッドのWhere句を削除し、次のように使用することができます: ' bool isDisposible = methodInfo.DeclaringType.GetInterfaceMap(typeof(IDisposable))。TargetMethods.Any(x => x == methodInfo) ; ' –

    関連する問題