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


74

我有一个物体让我们称之为 ObjectA

该对象具有10个属性,并且全部是字符串。

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

无论如何要检查所有这些属性是否为null或为空?

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

如果其中任何一个不为null或为空,则返回为false。如果它们全部为空,则应返回true。

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

谢谢


4
用反射尝试一下。
Ondrej Janacek 2014年

1
反思,但问问自己...数据结构是一种好方法吗?好像myObject真的只是一个数组。
CodingIntrigue 2014年

2
这个想法是在Web开发中,我有一个viewmodel(搜索过滤器),当它们将所有过滤器都留空时,linq语句从数据库返回所有结果。我以某种方式提出了一个想法,即如果那些过滤器从viewmodel中返回为空,则不应应用该过滤器。但是,写10的话听起来并不好。
2014年

Answers:


105

您可以使用反射来做

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的替代方法:

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

如果您具有ID属性或需要排除的属性,则可以检查:if(pi.Name.Equals(“ InfoID”)|| pi.Name.Equals(“ EmployeeID”)|| pi.Name.Equals(“ LastUpdated “))继续;
Kremena Lalova

16

我想您想确保所有属性都已填写。

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

流利的验证是一个不错的框架(http://fluentvalidation.codeplex.com),用于进行验证。例:

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

用法:

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

PS-在这种情况下使用反射只会使您的代码难以阅读。如上所示,使用验证可以清楚地知道您的规则是什么;您可以轻松地用其他规则扩展它们。


10

干得好

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

这是课程

class ObjectA
{
    public string A { get; set; }
    public string B { get; set; }
}

1
它说不能在两个地方都解析p.GetValue(myObj)?
2014年

尝试复制并粘贴我的答案。类本身,然后是代码,请再次运行它。
Ondrej Janacek 2014年

1
请,如果您对我的回答不满意,请告诉我原因。如果我不知道为什么他们会被否决,我还能如何改善它们。
Ondrej Janacek 2014年

我没有拒绝您的回答,但您的回答对我不起作用。我正在说的对象是ActionResult SearchResult(MyObjectViewModel myObj){}
akd 2014年

2
编辑您的问题,然后在其中添加您要尝试的确切代码,并清楚说明您遇到的错误。我发布了一个笼统的答案,因为您问了一个笼统的问题。您的问题与视图和控制器无关。
Ondrej Janacek 2014年

6

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

  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.

5

表达linq以查看对象的所有字符串属性是否都是非null和非空的一种略有不同的方式:

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

这有效,但是假设对象具有property ID,我可以获取ID为null还是空的ID吗?
Shaiju T

@stom您可以添加过滤器以检查Name和值。
马修·沃森

谢谢,我不明白您的意思是什么过滤器,但我会做一些研究。
Shaiju T

保留财产的权利;组; 或GetProperties中不会工作,看到stackoverflow.com/questions/7838189/...
宇阳剑

3

请注意,如果您具有数据结构层次结构,并且想要测试该层次结构中的所有内容,则可以使用递归方法。这是一个简单的例子:

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

2

您可以使用反射和扩展方法来执行此操作。

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

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

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

0

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

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

或者,如果属性全部相同,而您只想解析它们并找到单个null或空值,也许某种形式的字符串集合对您有用?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.