I want to determine if a generic object type (\"T\") method type parameter is a collection type. I would typically be sending T through as a Generic.List but it could be any co
For simplicity and code sharing, I usually use this extension method:
public static bool IsGenericList(this object obj)
{
return IsGenericList(obj.GetType());
}
public static bool IsGenericList(this Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
foreach (Type @interface in type.GetInterfaces())
{
if (@interface.IsGenericType)
{
if (@interface.GetGenericTypeDefinition() == typeof(ICollection<>))
{
// if needed, you can also return the type used as generic argument
return true;
}
}
}
return (type.GetInterface("IEnumerable") != null);
}
I love generics. In this method T
must have a public and parameterless constructor which means you can not use IList<object>
for T
. You must use List<object>
public static T IsEnumerable<T>() where T : new() {
if (new T() is IEnumerable) {
}
While I can't be certain what the original poster's intent was, there have been several responses to the effect of casting to IEnumerable for testing. That's fine, but everyone should be aware that string instances pass this test, which may not be something the original author intended. I know I certainly didn't when I went looking for an answer and found this post:
string testString = "Test";
Console.WriteLine(testString as IEnumerable != null); // returns true
I am in the process of trying to write a custom serializer that uses reflection to accomplish certain tasks. As part of a task, I need to determine if a property value is a collection/array/list of items or a single property value. What is particularly annoying is that several Linq expressions actually result in an enumerable type value, but GetType().IsArray returns false for these, and casting them to ICollection returns null as well, but casting them to IEnumerable returns a non-null value.
So...for the time being, I am still seeking a solution that works for all cases.
I came across the same issue while attempting to serialize any object to JSON format. Here is what I ended up using:
Type typ = value.GetType();
// Check for array type
if(typeof(IEnumerable).IsAssignableFrom(typ) || typeof(IEnumerable<>).IsAssignableFrom(typ))
{
List<object> list = ((IEnumerable)value).Cast<object>().ToList();
//Serialize as an array with each item in the list...
}
else
{
//Serialize as object or value type...
}
This will be the simplest check..
if(Obj is ICollection)
{
//Derived from ICollection
}
else
{
//Not Derived from ICollection
}