97

I have an object, lets call it ObjectA, and that object has 10 properties that are all strings.

var myObject = new {Property1="",Property2="",Property3="",Property4="",...}

Is there anyway to check to see whether all these properties are null or empty?

Any built-in method that would return true or false?

If any single of them is not null or empty then the return would be false, and if all of them are empty it should return true.

I'd just like to avoid writing 10 if statements to control for each of the properties being empty or null.

zcoop98
  • 2,590
  • 1
  • 18
  • 31
akd
  • 6,538
  • 16
  • 70
  • 112
  • 4
    Try it with reflection. – Ondrej Janacek Mar 27 '14 at 09:21
  • 1
    Reflection, but ask yourself...Is that data structure a good approach? Seems like `myObject` is *really* just an array. – CodingIntrigue Mar 27 '14 at 09:22
  • 3
    The idea is in the web development that I have a viewmodel(search filters) and when they leave all filters empty the linq statement returns all the result from database. I somehow came up with the idea that if those filters are returned empty from viewmodel it should not apply the filter. But writing 10 if else doesnot sound good at all. – akd Mar 27 '14 at 09:25
  • This question is really confusing and ambiguous. Are you asking to check they are all null? all empty? none are null? none are empty? all are null or empty? none are null or empty? – Caltor Mar 29 '22 at 09:34

11 Answers11

149

You can do it using Reflection

bool IsAnyNullOrEmpty(object myObject)
{
    foreach(PropertyInfo pi in myObject.GetType().GetProperties())
    {
        if(pi.PropertyType == typeof(string))
        {
            string value = (string)pi.GetValue(myObject);
            if(string.IsNullOrEmpty(value))
            {
                return true;
            }
        }
    }
    return false;
}

Matthew Watson suggested an alternative using LINQ:

return myObject.GetType().GetProperties()
    .Where(pi => pi.PropertyType == typeof(string))
    .Select(pi => (string)pi.GetValue(myObject))
    .Any(value => string.IsNullOrEmpty(value));
Leandro Bardelli
  • 10,561
  • 15
  • 79
  • 116
helb
  • 7,609
  • 8
  • 36
  • 58
21

I suppose you want to make sure that all properties are filled in.

A better option is probably by putting this validation in the constructor of your class and throw exceptions if validation fails. That way you cannot create a class that is invalid; catch exceptions and handle them accordingly.

Fluent validation is a nice framework (http://fluentvalidation.codeplex.com) for doing the validation. Example:

public class CustomerValidator: AbstractValidator<Customer> 
{
    public CustomerValidator()
    {
        RuleFor(customer => customer.Property1).NotNull();
        RuleFor(customer => customer.Property2).NotNull();
        RuleFor(customer => customer.Property3).NotNull();
    }
}

public class Customer
{
    public Customer(string property1, string property2, string property3)
    {
         Property1  = property1;
         Property2  = property2;
         Property3  = property3;
         new CustomerValidator().ValidateAndThrow();
    }

    public string Property1 {get; set;}
    public string Property2 {get; set;}
    public string Property3 {get; set;}
}

Usage:

 try
 {
     var customer = new Customer("string1", "string", null);
     // logic here
 } catch (ValidationException ex)
 {
     // A validation error occured
 }

PS - Using reflection for this kind of thing just makes your code harder to read. Using validation as shown above makes it explicitly clear what your rules are; and you can easily extend them with other rules.

U007D
  • 5,772
  • 2
  • 38
  • 44
L-Four
  • 13,345
  • 9
  • 65
  • 109
18

The following code returns if any property is not null.

  return myObject.GetType()
                 .GetProperties() //get all properties on object
                 .Select(pi => pi.GetValue(myObject)) //get value for the property
                 .Any(value => value != null); // Check if one of the values is not null, if so it returns true.
12

Here you go

var instOfA = new ObjectA();
bool isAnyPropEmpty = instOfA.GetType().GetProperties()
     .Where(p => p.GetValue(instOfA) is string) // selecting only string props
     .Any(p => string.IsNullOrWhiteSpace((p.GetValue(instOfA) as string)));

and here's the class

class ObjectA
{
    public string A { get; set; }
    public string B { get; set; }
}
Ondrej Janacek
  • 12,486
  • 14
  • 59
  • 93
  • 1
    it says cannot resolve p.GetValue(myObj) in both place? – akd Mar 27 '14 at 09:38
  • Try copy-paste my answer. The class itself and then the code and run it again, please. – Ondrej Janacek Mar 27 '14 at 09:48
  • 1
    Please, if you downvote my answer, tell me why. How else could I improve them if I don't know why they are being downvoted. – Ondrej Janacek Mar 27 '14 at 10:02
  • I didnt downvote your answer but your answer doesnt work for me. the object I am talking is something ActionResult SearchResult(MyObjectViewModel myObj) {} – akd Mar 27 '14 at 10:16
  • so those myObj has got strings properties which are filled by user and sends to server. then on controller I am trying to controller whether those are all empty or not – akd Mar 27 '14 at 10:16
  • 2
    Edit your questions and add there the exact code you are trying and explain clearly what error are you getting, please. I posted a general answer because you askwed a general question. There's nothing about views and controllers in your question. – Ondrej Janacek Mar 27 '14 at 11:00
6

A slightly different way of expressing the linq to see if all string properties of an object are non null and non empty:

public static bool AllStringPropertyValuesAreNonEmpty(object myObject)
{
    var allStringPropertyValues = 
        from   property in myObject.GetType().GetProperties()
        where  property.PropertyType == typeof(string) && property.CanRead
        select (string) property.GetValue(myObject);

    return allStringPropertyValues.All(value => !string.IsNullOrEmpty(value));
}
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
3

Note if you've got a data structural hierarchy and you want to test everything in that hierarchy, then you can use a recursive method. Here's a quick example:

static bool AnyNullOrEmpty(object obj) {
  return obj == null
      || obj.ToString() == ""
      || obj.GetType().GetProperties().Any(prop => AnyNullOrEmpty(prop.GetValue(obj)));
}
Michael
  • 8,362
  • 6
  • 61
  • 88
Dax Fohl
  • 10,654
  • 6
  • 46
  • 90
3

To only check if all properties are null:

bool allPropertiesNull = !myObject.GetType().GetProperties().Any(prop => prop == null);
Martin
  • 2,411
  • 11
  • 28
  • 30
Tessa
  • 37
  • 1
2

you can use reflection and extension methods to do this.

using System.Reflection;
public static class ExtensionMethods
{
    public static bool StringPropertiesEmpty(this object value)
    {
        foreach (PropertyInfo objProp in value.GetType().GetProperties())
        {
            if (objProp.CanRead)
            {
                object val = objProp.GetValue(value, null);
                if (val.GetType() == typeof(string))
                {
                    if (val == "" || val == null)
                    {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}

then use it on any object with string properties

test obj = new test();
if (obj.StringPropertiesEmpty() == true)
{
    // some of these string properties are empty or null
}
naffy
  • 111
  • 4
0

No, I don't think there is a method to do exactly that.

You'd be best writing a simple method that takes your object and returns true or false.

Alternatively, if the properties are all the same, and you just want to parse through them and find a single null or empty, perhaps some sort of collection of strings would work for you?

0

You can try the following query :

if the object is "referenceKey" (where few properties may be null )

referenceKey.GetType().GetProperties().Where(x => x.GetValue(referenceKey) == null)

I need to count the properties where the value is set to not Null, so I have used the following query :

 var countProvidedReferenceKeys = referenceKey.GetType().GetProperties().Where(x => x.GetValue(referenceKey) != null).Count();
Tanvir Anowar
  • 75
  • 1
  • 1
  • 7
0

In my case all properties where nullable and had to check if all null, so I did the count compare, created this extension method:

public static bool IsObjectNull(this object obj)
{
  return obj.GetType().GetProperties().Count() == obj.GetType().GetProperties().Where(x => x.GetValue(obj) == null).Count();
}
dawncode
  • 578
  • 1
  • 8
  • 22