ランタイムタイプがコレクションタイプであるかどうかを判断しようとしています。私が下に持っているものは動作しますが、私がやったように配列のコレクション型であると信じている型に名前を付ける必要があるのは奇妙に思えます。
以下のコードでは、ジェネリックロジックの理由は、私のアプリでは、すべてのコレクションがジェネリックであることを期待しているためです。
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));
}
このコードをリファクタリングして、よりスマートまたはシンプルにするにはどうすればよいですか?
実際、これらすべてのタイプは IEnumerable
を継承します。確認できるのはそれだけです:
bool IsEnumerableType(Type type)
{
return (type.GetInterface(nameof(IEnumerable)) != null);
}
または、本当にICollectionを確認する必要がある場合:
bool IsCollectionType(Type type)
{
return (type.GetInterface(nameof(ICollection)) != null);
}
「構文」の部分を見てください:
このスレッドは古いことは知っていますが、Microsoft is キーワードによると、2015年7月20日現在の最新の例です。
if(collection is ICollection) return true;
このヘルパーメソッドを使用して、型がオープンジェネリックインターフェイスを実装しているかどうかを確認できます。あなたの場合、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
を実装する型をコレクションとは呼びません。
それらはすべてIEnumerable()を継承します。つまり、 its there で十分なはずです。
Linqを使用して、次のようなインターフェイス名を検索できます。
yourobject.GetType().GetInterfaces().Where(s => s.Name == "IEnumerable")
これに値がある場合、IEnumerable
のインスタンスです。