Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to test if a Type is a collection

I have a method that accepts a parameter obj of type System.Object

Now I want to check if the actual type of obj is:

  • A collection type (IEnumerable).
  • Anything else.

The first way I thought of is:

if (obj is IEnumerable) 
   // obj is a collection

But System.String implements IEnumerable, and I don't want to treat string as a collection.

The second way I thought is testing for ICollection instead of IEnumerable, since IEnumerable is more of a potential collection than an actual one. This would leave out string, but also ICollection-Of-T because it does not inherit ICollection (IEnumerable-Of-T is the only generic collection abstraction that's backwards compatible - it inherits IEnumerable).

So I guess the best way is:

if (obj is string) 
  // not a collection
else if (obj is IEnumerable) 
  // collection
else
  // not a collection

Is there a better way?

like image 696
Max Toro Avatar asked Jul 24 '09 23:07

Max Toro


2 Answers

I think you're over complicating this a bit. If you really want to use IEnumerable but exclude System.String, why not just do that directly in code?

public static bool IsCollection(object obj) {
  return obj is IEnumerable && !(obj is String);
}
like image 184
JaredPar Avatar answered Oct 14 '22 03:10

JaredPar


If you really only want to test:

bool isCollection = obj.GetType().GetInterfaces()
    .Any(iface => iface.GetGenericTypeDefinition() == typeof(ICollection<>))

But frankly, if you really only want to special-case string (why, by the way?), then just do so. If you test for ICollection<>, you will treat the result of a LINQ query as "non-collection", for example, for no good reason.

like image 5
Pavel Minaev Avatar answered Oct 14 '22 02:10

Pavel Minaev