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 IEnumerable
s?
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