Reputation: 28608
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:
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?
Upvotes: 7
Views: 6371
Reputation: 101555
If you really only want to test:
bool isCollection = obj.GetType().GetInterfaces()
.Any(iface => iface.IsGenericType && 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.
Upvotes: 5
Reputation: 149
If you want to do a check and get true for tpyes (includes nullables) any list/collection/IEnumerable, but get false for type of string, then
private static bool IsIEnumerable(Type requestType)
{
var isIEnumerable = typeof(IEnumerable).IsAssignableFrom(requestType);
var notString = !typeof(string).IsAssignableFrom(requestType);
return isIEnumerable && notString;
}
Upvotes: -1
Reputation: 754505
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);
}
Upvotes: 10