关于c#:如何检查对象的所有属性是null还是空?

How to check all properties of an object whether null or empty?

我有一个对象,我们称之为ObjectA

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

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

是否仍要检查所有这些属性是否为空?

那么,是否有任何内置方法会返回true或false?

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

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

谢谢


你可以用反射来做

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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建议使用Linq:

1
2
3
4
return myObject.GetType().GetProperties()
    .Where(pi => pi.PropertyType == typeof(string))
    .Select(pi => (string)pi.GetValue(myObject))
    .Any(value => string.IsNullOrEmpty(value));


我想你要确保所有的财产都填好了。

更好的选择可能是将此验证放入类的构造函数中,如果验证失败,则抛出异常。这样就不能创建无效的类;捕获异常并相应地处理它们。

Fluent验证是一个很好的验证框架(http://fluent validation.codeplex.com)。例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;}
}

用途:

1
2
3
4
5
6
7
8
 try
 {
     var customer = new Customer("string1","string", null);
     // logic here
 } catch (ValidationException ex)
 {
     // A validation error occured
 }

ps-对这类事情使用反射只会使代码更难阅读。使用上面所示的验证可以明确地说明您的规则是什么;您可以使用其他规则轻松地扩展它们。


干得好

1
2
3
4
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)));

这是班级

1
2
3
4
5
class ObjectA
{
    public string A { get; set; }
    public string B { get; set; }
}


表示LINQ的一种稍有不同的方法,以查看对象的所有字符串属性是否为非空和非空:

1
2
3
4
5
6
7
8
9
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));
}


如果任何属性不为空,则返回以下代码。

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

注意,如果您有一个数据结构层次结构,并且希望测试该层次结构中的所有内容,那么您可以使用递归方法。下面是一个简单的例子:

1
2
3
4
5
static bool AnyNullOrEmpty(object obj) {
  return obj == null
      || obj.ToString() ==""
      || obj.GetType().GetProperties().Any(prop => AnyNullOrEmpty(prop.GetValue(obj)));
}


您可以使用反射和扩展方法来实现这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
    }
}

然后在具有字符串属性的任何对象上使用它

1
2
3
4
5
test obj = new test();
if (obj.StringPropertiesEmpty() == true)
{
    // some of these string properties are empty or null
}

仅检查所有属性是否为空:

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

不,我认为没有办法做到这一点。

您最好编写一个简单的方法,它获取对象并返回true或false。

或者,如果属性都是相同的,并且您只想通过它们进行分析并找到一个空的或空的,那么也许某种类型的字符串集合对您有用?