【问题标题】:How check whether class members are not null or empty如何检查类成员是否不为空或为空
【发布时间】:2012-01-05 08:10:18
【问题描述】:

我有一个只有这样的字符串成员的类:

public class MyClass
{
    public string MyProp1 { get; set; }
    public string MyProp2 { get; set; }
}

我创建了一个实例:

Var myClass = new MyClass();

在后面的代码中,我想知道所有成员(MyProp1 和 MyProp2)是否不为 null 或为空。我知道我当然可以使用if,但是在我的真实代码中,属性比 2 多得多。

有没有办法做到这一点?

谢谢,

【问题讨论】:

  • 您需要知道哪些属性是 NULL 或 string.Empty 还是至少其中一个是?
  • 属性不能为空,不能为空

标签: c#


【解决方案1】:

为您的属性使用基于字典的存储可能是最简单的方法:

public class MyClass
{
    private IDictionary<String, String> _store;

    public MyClass()
    {
        _store = new Dictionary<String, String>();
    }

    public string MyProp1 { 
        get { return GetOrDefault("MyProp1"); }
        set { _store["MyProp1"] = value; }
    }
    public string MyProp2 { 
        get { return GetOrDefault("MyProp2"); }
        set { _store["MyProp2"] = value; }
    }

    public Boolean HasData()
    {
        return _store.Any(x => !String.IsNullOrWhiteSpace(x.Value));
    }

    public Boolean IsEmpty()
    {
        return _store.All(x => String.IsNullOrWhiteSpace(x.Value));
    }   

    private String GetOrDefault(String propertyName)
    {
        if (_store.ContainsKey(propertyName))
        {
            return _store[propertyName];
        }

        return String.Empty;
    }
}

另一种方法是将其与默认实例进行比较:

public class MyClass
{
    public string MyProp1 { get; set; }
    public string MyProp2 { get; set; }

    public static readonly MyClass Empty = new MyClass();

    public Boolean HasData()
    {
        return !Empty.Equals(this);
    }

    public Boolean IsEmpty()
    {
        return Empty.Equals(this);
    }
}

【讨论】:

  • 注意:在你的代码中你会得到System.Collections.Generic.KeyNotFoundException,如果你在没有先设置的情况下调用MyProp1!至少使用get { return _store.ContainsKey("MyProp1") ? _store["MyProp1"] : String.Empty; }
  • @balexandre:很好,我已经根据你的建议更新了答案。
  • 与默认实例比较:好主意。
【解决方案2】:

您可以尝试使用反射来检查属性。您应该需要确认所有属性都是公共的,并且类型是字符串。这是代码。

    public static bool IsNullOrEmpty(MyClass prop)
    {
        bool result = true;

        PropertyInfo[] ps = prop.GetType().GetProperties();

        foreach (PropertyInfo pi in ps)
        {
            string value = pi.GetValue(prop, null).ToString();

            if (string.IsNullOrEmpty(value))
            {
                result = false;
                break;
            }
        }

        return result;
    }

【讨论】:

  • 任何框架都可以为我们完成这项工作?努尼特?或起订量???还是应该由用户检查? ??
【解决方案3】:

检查您的类是否包含“任何”为空的属性:

System.Reflection.PropertyInfo[] properties = myClass.GetType().GetProperties
                         (BindingFlags.Public | BindingFlags.Instance);         

bool hasNullProperty = properties.Any(y => y.GetValue(x, null) == null);

【讨论】:

    【解决方案4】:

    你总是可以像这样初始化你的类

    public class MyClass
    {
        public MyClass() {
            this.MyProp1 = this.MyProp2 = String.Empty;
        }
    
        public string MyProp1 { get; set; }
        public string MyProp2 { get; set; }
    }
    

    并且,除非您以编程方式为其分配 null 值,否则 new MyClass() 将始终在其 2 个属性中包含 String.Empty...


    来自评论:

    在这些情况下我所做的是调用帮助程序,例如:string name = myHelper.CheckNode(xmlNode);在那个助手中,我检查它是否为空,任何其他检查,我可以轻松地调整助手方法,它将可用于所有元素,并且您可以扩展它以不仅支持字符串,还支持所有其他数据类型

    因此,假设您正在从 XML 中读取节点,您可以这样编写它们:

    string name = myHelper.CheckNode(node);
    

    在你的助手中,你可以有类似的东西:

    XmlNodeList datasourceNodes = rootNode.SelectNodes("dataSources/dataSource");
    foreach (XmlNode datasourceNode in datasourceNodes)
    {
        DataSource dataSource = new DataSource();
        dataSource.Name = myHelper.CheckAttr(datasourceNode.Attributes["name"]);
        dataSource.ODBC = myHelper.CheckNode(datasourceNode.SelectSingleNode("odbc"));
    
        // or a variant (Extension Method)
        dataSource.UID  = datasourceNode.CheckNode("user");
        dataSource.PWD  = datasourceNode.CheckAttr("password");
    
        ds.Add(dataSource);
    }
    

    你的助手可以有这样的方法:

    public static string CheckAttr(XmlAttribute attr) 
    {
        return attr == null ? "" : attr.Value.Trim();
    }
    public static string CheckNode(XmlNode node) 
    {
        return node == null ? "" : node.InnerText.Trim();
    }
    

    或用于变体(扩展方法)

    public static string CheckAttr(this XmlNode, string attrName)
    {
        return attrName[attrName] == null ? "" : attrName[attrName].Value.Trim();
    }
    public static string CheckNode(this XmlNode, string nodeName)
    {
        return node.SelectSingleNode(nodeName) == null ? 
                     "" : 
                     node.SelectSingleNode(nodeName).InnerText.Trim();
    }
    

    【讨论】:

    • 我的解释可能不好。成员是通过读取 XML 文件设置的,但我想确保所有成员都不为空或为空
    • 在这些情况下我所做的是调用一个助手,例如:string name = myHelper.CheckNode(xmlNode); 并且在那个助手中我检查它是否是 null,任何其他检查,我可以轻松地调整助手方法和它将可用于所有元素,您可以将其扩展为不仅支持strings,还支持所有其他数据类型。
    【解决方案5】:

    如果类中有许多属性,一种处理方法是将它们存储在集合中,例如数组或字典,而不是将每个属性声明为类的单独成员。

    然后就可以通过key来访问字典中的数据,就像访问一个类的属性一样简单。而且好处是可以循环遍历字典,循环检查所有属性。

    【讨论】:

      【解决方案6】:

      我建议在您的类中创建一个函数,您可以在其中检查 String.IsNullOrEmpty(MyProp1) 等以获取您的所有属性。通过这种方式,您至少可以将所有检查功能集中在一个地方。并且您只有在添加新属性时才能修改此位置。

      【讨论】:

      • 只是不想做……一一检查
      • 除非你想创建一个函数来遍历类中的所有成员(例如,这里描述的stackoverflow.com/questions/721441/…),你必须以某种方式做到这一点。只要你为它创建一个函数,你只需要做一次......反射是一个更通用的解决方案,创建你自己的函数手动检查每个属性会产生更好的性能(并给你更多的控制)。
      【解决方案7】:

      要检查是否设置了所有元素,您可以向您的类添加一个IsEmpty() 方法来检查内部属性。这样您就不必在代码中到处重复 if 语句了。

      IsEmpty() 方法中,您可以使用常规 if 语句检查所有字段,也可以使用反射自动检索所有字符串属性并检查它们的值。反射的性能会比正常的 if 检查更差,但如果这不是问题,您可以在所有实体中重用反射代码来检查它们的值。

      【讨论】:

        【解决方案8】:

        通过使用 Attribute Base 编程,您可以实现这一点。在这种方法中,您需要将属性放在类成员上,并且可以进行验证。您也可以为此使用Microsoft Enterprise Library

        【讨论】:

          【解决方案9】:

          可能最好的方法是:

          以字符串字典的形式重组您的属性。遍历字典以使用 string.IsNullOrEmpty() 测试字符串。您可以将 N 个 getter/setter 替换为单个 Indexer 属性,该属性根据键直接从字典中设置和检索字符串

          【讨论】:

            【解决方案10】:

            您可以尝试以下样式。我之前没有尝试过,但你可能会看到它是否有帮助

            If (String.IsNullOrEmpty(string1 && string2 && string3)) 
            

            【讨论】:

              猜你喜欢
              • 2023-03-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-11-04
              • 2015-06-05
              相关资源
              最近更新 更多