49

ランタイムタイプがある種のコレクションタイプであるかどうかを判断しようとしています。以下に示すものは機能しますが、私が行ったように、配列内のコレクション型であると私が信じる型に名前を付ける必要があるのは奇妙に思えます。

以下のコードでは、汎用ロジックの理由は、私のアプリでは、すべてのコレクションが汎用であると期待しているためです。

bool IsCollectionType(Type type)
{
    if (!type.GetGenericArguments().Any())
        return false;

    Type genericTypeDefinition = type.GetGenericTypeDefinition();
    var collectionTypes = new[] { typeof(IEnumerable<>), typeof(ICollection<>), typeof(IList<>), typeof(List<>) };
    return collectionTypes.Any(x => x.IsAssignableFrom(genericTypeDefinition));
}

このコードをよりスマートまたはシンプルにリファクタリングするにはどうすればよいですか?

4

4 に答える 4

88

実際、これらのタイプはすべてを継承しIEnumerableます。あなたはそれだけをチェックすることができます:

bool IsEnumerableType(Type type)
{
    return (type.GetInterface(nameof(IEnumerable)) != null);
}

または、本当にICollectionをチェックする必要がある場合:

bool IsCollectionType(Type type)
{
    return (type.GetInterface(nameof(ICollection)) != null);
}

「構文」の部分を見てください。

于 2012-06-02T17:53:14.093 に答える
4

このヘルパーメソッドを使用して、型がオープンジェネリックインターフェイスを実装しているかどうかを確認できます。あなたの場合、あなたは使うことができますDoesTypeSupportInterface(type, typeof(Collection<>))

public static bool DoesTypeSupportInterface(Type type,Type inter)
{
    if(inter.IsAssignableFrom(type))
        return true;
    if(type.GetInterfaces().Any(i=>i. IsGenericType && i.GetGenericTypeDefinition()==inter))
        return true;
    return false;
}

または、非ジェネリックをチェックするだけですIEnumerable。すべてのコレクションインターフェイスはそれを継承します。IEnumerableただし、コレクションを実装するタイプは呼び出しません。

于 2012-06-02T17:54:51.140 に答える
1

linqを使用して、次のようなインターフェイス名を検索できます

yourobject.GetType().GetInterfaces().Where(s => s.Name == "IEnumerable")

これに値がある場合は、のインスタンスですIEnumerable

于 2015-09-25T19:18:19.587 に答える
0

このソリューションはとを処理ICollectionICollection<T>ます。

    static bool IsCollectionType(Type type)
    {
        return type.GetInterfaces().Any(s => s.Namespace == "System.Collections.Generic" && (s.Name == "ICollection" || s.Name.StartsWith("ICollection`")));
    }
于 2021-05-18T08:27:35.493 に答える