如何检查对象的所有属性是空还是空?

我有一个对象,让我们叫它 ObjectA

这个对象有10个属性,这些都是字符串。

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

是否有办法检查所有这些属性是空还是空?

那么有没有内置的方法可以返回 true 或 false 呢?

如果它们中的任何一个不为 null 或空,那么返回值将为 false。如果它们都是空的,那么它应该返回 true。

我不想写10 if 语句来控制这些属性是空还是空。

谢谢

141082 次浏览

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));

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.

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?

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; }
}

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));
}

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
}

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)));
}

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.

To only check if all properties are null:

bool allPropertiesNull = !myObject.GetType().GetProperties().Any(prop => prop == null);

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();