35

私はインターフェースを持っています

public interface MyInterface<TKey, TValue>
{
}

実装は無関係です。ここで、特定の型がそのインターフェイスの実装であるかどうかを確認したいと思います。このメソッドは失敗します

public class MyClass : MyInterface<int, string>
{
}

しかし、私はチェックを行う方法がわかりません。

public void CheckIfTypeImplementsInterface(Type type)
{
    var result1 = typeof(MyInterface<,>).IsAssignableFrom(type); --> false
    var result2 = typeof(MyInterface<int,string>).IsAssignableFrom(type); --> true
}

result1 が true になるにはどうすればよいですか?

4

2 に答える 2

54

私の知る限り、これを行う唯一の方法は、すべてのインターフェイスを取得し、ジェネリック定義が必要なインターフェイス タイプと一致するかどうかを確認することです。

bool result1 = type.GetInterfaces()
    .Where(i => i.IsGenericType)
    .Select(i => i.GetGenericTypeDefinition())
    .Contains(typeof(MyInterface<,>));

編集:ジョンがコメントで指摘しているように、次のこともできます。

bool result1 = type.GetInterfaces()
    .Where(i => i.IsGenericType)
    .Any(i => i.GetGenericTypeDefinition() == typeof(MyInterface<,>));
于 2013-08-14T13:43:36.437 に答える
3

一般に、このような動作は、ジェネリック型パラメーターに依存しない機能がインターフェイスに含まれている場合にのみ必要です。インターフェイスを制御できる場合、最適な解決策は、型に依存しない部分から型​​に依存する部分を継承することです。たとえば、既存のコレクション インターフェイスが存在しない場合は、次のように定義できます。

interface ICountable 
  { CollectionAttribute Attributes {get;} int Count {get;} }
interface ICollection<T> : IEnumerable<T> ICountable
  { ... and other stuff ... }

そのようなことが で行われた場合、 を期待していたが実装したばかりの型のオブジェクトを取得ICollectionしたコードは、そのオブジェクトのメンバーを使用しても問題ありません(非ジェネリックを実装することに注意してください。ただし、他の実装ではそうではない可能性があります)。IEnumerable<Animal>CatListIList<Cat>CountList<Animal>ICollectionIList<Animal>

現状では、を期待しているときにコードに何らかのCount方法で のメソッドを見つけさせるというタスクに行き詰まっている場合は、 のようなものを構築して、実装を見つけたらデリゲートを構築できるようにすることは価値があるかもしれません。その引数を にキャストし、それを呼び出して、その結果を返すメソッドに。そのようなディクショナリがある場合、別のディクショナリがあれば、ディクショナリからデリゲートを簡単に呼び出すことができます。ICollection<Cat>IEnumerable<Animal>Dictionary<Type, Func<IEnumerable<Animal>, int>CatListICollection<Cat>.CountICollection<Cat>CountCatList

于 2013-08-14T16:06:30.570 に答える