First of all I'd reduce indentation. It makes your code really too hard to read. Doing that you will see it may be simplified.
First of all try
/catch
: a catch-all block where you rethrow the exception is useless (and you may even throw away line number information.)
This code:
if (obj != null){ // Do something...}
May be replaced simply with:
if (obj == null) return false;
You do not need to declare a local variable for result
, simply return its value where appropriate.
You do not have to check condition result == false
inside your foreach
loop (you will still enumerate through all properties), simply break
the loop and exit immediately.
You do not need to use to dynamic
, when casting you have the right type at compile-time. Also move all this code inside a separate function:
private static bool IsNullOrEmpty(object obj) {}
Let's see how to fill this function. Let's read the value of the property:
object value = pi.GetValue(obj);
First of all a common case, valid for all reference types:
if (Object.ReferenceEquals(value, null)) return true;
Then explicitly check for strings:
if (value is string && String.IsNullOrEmpty((string)value)) return true;
For Int32
(note that in your original code value <= 0 ? true : false
is redundant it may be simplified to value <= 0
). BTW are you sure you want to consider negative numbers as empty values?!
if (value is int) return ((int)value) <= 0;
Boolean
does not need to be checked in this case (null
case has been already handled). We just need to work out Guid
:
if (value is Guid) return ((Guid)value) == Guid.Empty;
That's all. Note that now or in future you may want to check for Nullable<T>
and or other types. With the exception of strings and negative integer numbers you can also do something like this:
if (Object.ReferenceEquals(value, null)) return true;var type = value.GetType();return type.IsValueType&& Object.Equals(value, Activator.CreateInstance(type));
What left in your original function? In this example let me use simplified check (negative numbers are not empty and I do not check for String.Empty
against strings however it handles nullable types), feel free to pick the one works for you:
public static bool IsAnyNullOrEmpty(object obj){ if (Object.ReferenceEquals(obj, null)) return true; return obj.GetType().GetProperties() .Any(x => IsNullOrEmpty(x.GetValue(obj)));}private static bool IsNullOrEmpty(object value){ if (Object.ReferenceEquals(value, null)) return true; var type = value.GetType(); return type.IsValueType&& Object.Equals(value, Activator.CreateInstance(type));}
Last note: if working with databases you may also want to check equality with DBNull.Value
.