【问题标题】:How to check all properties of an object whether null or empty?如何检查对象的所有属性是否为空或为空?
【发布时间】:2014-05-06 03:45:12
【问题描述】:

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

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

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

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

那么有什么内置的方法会返回真或假吗?

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

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

谢谢

【问题讨论】:

  • 用反射试试。
  • 反思,但问问你自己......那个数据结构是一个好方法吗?似乎myObject 真的只是一个数组。
  • 这个想法是在 Web 开发中,我有一个视图模型(搜索过滤器),当它们将所有过滤器留空时,linq 语句会返回数据库中的所有结果。我不知何故想出了一个想法,如果这些过滤器从视图模型返回为空,它不应该应用过滤器。但是写 10 if else 听起来一点都不好。

标签: c# properties


【解决方案1】:

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

  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.

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      你可以使用反射来做到这一点

      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")) 继续;
      • 如果字符串以外的任何其他属性类型都可以为空,这是否会中断?
      • linq 的完美创意
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        我想你想确保所有属性都被填写。

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

        Fluent 验证是一个很好的框架 (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 - 对这种事情使用反射只会使您的代码更难阅读。使用如上所示的验证可以明确地明确您的规则是什么;并且您可以使用其他规则轻松扩展它们。

        【讨论】:

          【解决方案6】:

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

          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
          }
          

          【讨论】:

            【解决方案7】:

            给你

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

            【讨论】:

            • 它说不能在这两个地方解析 p.GetValue(myObj)?
            • 尝试复制粘贴我的答案。请类本身,然后是代码并再次运行它。
            • 如果你不赞成我的回答,请告诉我原因。如果我不知道为什么它们被否决,我还能如何改进它们。
            • 我没有否决你的答案,但你的答案对我不起作用。我说的对象是 ActionResult SearchResult(MyObjectViewModel myObj) {}
            • 请编辑您的问题并在其中添加您正在尝试的确切代码,并清楚地解释您遇到的错误。我发布了一个一般性答案,因为您提出了一个一般性问题。您的问题中没有关于视图和控制器的内容。
            【解决方案8】:

            一种稍微不同的表达 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));
            }
            

            【讨论】:

            • 这行得通,但是假设对象具有属性 ID ,我可以获取属性为 null 或空的 ID 吗?
            • @stom 您可以添加过滤器来检查Name 和值。
            • 谢谢,我不明白你的意思是什么过滤器,但我会做一些研究。
            • 记得给属性get;放;否则 GetProperties 将不起作用,请参阅 stackoverflow.com/questions/7838189/…
            【解决方案9】:

            不,我不认为有一种方法可以做到这一点。

            你最好写一个简单的方法来获取你的对象并返回真或假。

            或者,如果属性都相同,而您只想解析它们并找到单个 null 或空,那么某种字符串集合可能对您有用?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-08-22
              • 2020-09-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-07-27
              • 1970-01-01
              相关资源
              最近更新 更多