インターフェースがあります
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にするにはどうすればよいですか?
私の知る限り、これを行う唯一の方法は、すべてのインターフェースを取得し、汎用定義が必要なインターフェースタイプと一致するかどうかを確認することです。
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<,>));
通常、このような動作は、ジェネリック型パラメーターに依存しない機能がインターフェイスに含まれている場合にのみ必要です。インターフェースを制御できる場合、最良の解決策は、タイプに依存する部分をタイプに依存しない部分から継承させることです。たとえば、既存のコレクションインターフェースが存在しない場合、次のように定義できます。
interface ICountable
{ CollectionAttribute Attributes {get;} int Count {get;} }
interface ICollection<T> : IEnumerable<T> ICountable
{ ... and other stuff ... }
そのようなことをICollection
で行った場合、IEnumerable<Animal>
を期待していたが、IList<Cat>
を実装するだけのCatList
タイプのオブジェクトを取得したコードは、そのオブジェクトのCount
メンバーを使用しても問題ありません(List<Animal>
はジェネリックではないICollection
を実装していることに注意してください。他のIList<Animal>
実装はそうではないかもしれません)。
このように、ICollection<Cat>
を期待しているときにコードが何らかの理由でIEnumerable<Animal>
のCount
メソッドを見つけるというタスクに行き詰まっている場合は、Dictionary<Type, Func<IEnumerable<Animal>, int>
のようなものを構築して、CatList
が実装されていることを確認することをお勧めします。 ICollection<Cat>.Count
引数をICollection<Cat>
にキャストし、Count
を呼び出して結果を返すメソッドへのデリゲートを構築できます。そのような辞書がある場合、別のCatList
が与えられれば、辞書からデリゲートを呼び出すだけで済みます。