Let's say I have an object which may be of type IEnumerable<T>. I want to write a method that returns true if the object is of type IEnumerable<T>, is not null, and is not empty.
Here's what I've got so far:
public bool IsNullOrEmpty(object obj)
{
if (obj != null)
{
if (obj is IEnumerable<object>)
{
return (obj as IEnumerable<object>).Any();
}
}
return false;
}
This works if I pass in an object that is of type List<string>, but not if I pass in an object that is of type List<int>. It fails because because obj is IEnumerable<object> returns false.
Any idea how I can make this work for all generic IEnumerables?
Since the type may be unknown, you can try check for IEnumerable interface and use MoveNext() on the enumerator.
EDIT: I updated the method name. It makes more sense with the logic now since the original question code was checking if there were items in the collection.
public bool IsNotNullOrEmpty(object enumerable)
{
if (enumerable != null)
{
if (enumerable is IEnumerable)
{
using(var enumerator = ((IEnumerable)enumerable).GetEnumerator())
return enumerator.MoveNext();
}
}
return false;
}
System.Collections.Generic.IEnumerable<T> inherits from System.Collections.IEnumerable - thus, if you are ok with checking the non-generic IEnumerable, rather than the generic IEnumerable<T>, you could just cast to IEnumerable.
A few notes about your code: You are first checking with is, and then you cast with as. That is generally unnecessary; as already checks and returns null if the cast failed. Therefore, a shorter way would be:
var enumerable = obj as IEnumerable;
if (enumerable != null) {
return !enumerable.Cast<object>().Any();
}
Note that you will need the additional call to Cast there, as Any requires a generic IEnumerable<T>.
You can try to cast it to IEnumerable:
public static bool IsNullOrEmpty<T>(this T obj) where T : class
{
if (obj == null) return true;
IEnumerable seq = obj as IEnumerable;
if (seq != null) return !seq.Cast<object>().Any();
return false;
}
...
List<int> list = new List<int>();
bool nullOrEmpty = list.IsNullOrEmpty(); // true
Btw, interestingly enough it works correctly with an empty string:
bool nullOrEmpty = "".IsNullOrEmpty(); // true
You can check for the non-generic IEnumerable and check that for emptiness. You can add a check to ensure the object implements IEnumerable<T> using reflection:
public static bool IsNullOrEmpty(object obj)
{
var e = obj as System.Collections.IEnumerable;
if (e == null || !e.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable<>))) return false;
foreach (object _ in e)
{
return true;
}
return false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With