web-dev-qa-db-ja.com

TypeまたはインスタンスがType Tに関係なくIEnumerableを実装しているかどうかを確認する

私は現在のプロジェクトに深く反省し、すべてを整頓するためにいくつかのヘルパーメソッドを提供しようとしています。

タイプまたはインスタンスがIEnumerableに関係なくTを実装しているかどうかを判断するメソッドのペアを提供したいと思います。ここに私が今持っているものがあります:

public static bool IsEnumerable(this Type type)
{
    return (type is IEnumerable);
}

public static bool IsEnumerable(this object obj)
{
    return (obj as IEnumerable != null);
}

を使用してテストするとき

Debug.WriteLine("Type IEnumerable:   " + typeof(IEnumerable).IsEnumerable());
Debug.WriteLine("Type IEnumerable<>: " + typeof(IEnumerable<string>).IsEnumerable());
Debug.WriteLine("Type List:          " + typeof(List<string>).IsEnumerable());
Debug.WriteLine("Type string:        " + typeof(string).IsEnumerable());
Debug.WriteLine("Type DateTime:      " + typeof(DateTime).IsEnumerable());
Debug.WriteLine("Instance List:      " + new List<string>().IsEnumerable());
Debug.WriteLine("Instance string:    " + "".IsEnumerable());
Debug.WriteLine("Instance DateTime:  " + new DateTime().IsEnumerable());

結果としてこれを取得します:

Type IEnumerable:   False
Type IEnumerable<>: False
Type List:          False
Type string:        False
Type DateTime:      False
Instance List:      True
Instance string:    True
Instance DateTime:  False

Typeメソッドはまったく機能しないようです。少なくともSystem.Collections.IEnumerableの直接一致にはtrueが必要でした。

stringは、いくつかの注意事項はありますが、技術的には列挙可能です。ただし、理想的には、この場合、falseを返すヘルパーメソッドが必要です。 trueを返すには、定義済みのIEnumerable<T>型のインスタンスが必要です。

たぶんかなり明白なものを見逃しただけです。誰かが正しい方向に私を向けることができますか?

28
Octopoid

次の行

return (type is IEnumerable);

Typeのインスタンス、typeIEnumerableである場合」と尋ねていますが、明らかにそうではありません。

あなたがしたいことは:

return typeof(IEnumerable).IsAssignableFrom(type);
45
dav_i

Type.IsAssignableFrom(Type) に加えて、 Type.GetInterfaces() も使用できます。

public static bool ImplementsInterface(this Type type, Type interface)
{
    bool implemented = type.GetInterfaces().Contains(interface);
    return implemented;
}

そうすれば、複数のインターフェースをチェックしたい場合、ImplementsInterfaceを簡単に変更して複数のインターフェースを取得できます。

10
Wai Ha Lee