如何检查类成员是否不为null或空?

3

我有一个只包含字符串成员的类,像这样:

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

我创建了一个实例:

Var myClass = new MyClass();

在代码的后面,我想知道所有成员(MyProp1和MyProp2)是否都不为空或空字符串。当然我知道可以使用if语句,但在我的实际代码中有更多的属性。
是否有一种方法可以做到这一点?
谢谢。

你需要知道哪些属性是NULL或string.Empty,还是只需要知道它们中至少有一个是这样的? - ChrisBD
属性不能为 null 也不能为空。 - TheBoubou
10个回答

10

使用基于字典的存储方式可能是实现此目的最简单的方法:

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

1
请注意:在您的代码中,如果您在先不设置MyProp1的情况下调用它,您将会收到 System.Collections.Generic.KeyNotFoundException 的错误提示!至少使用 get { return _store.ContainsKey("MyProp1") ? _store["MyProp1"] : String.Empty; } - balexandre
@balexandre:好主意,我已经采纳了你的建议并更新了答案。 - Pondidum
2
与默认实例相比:绝妙的想法。 - Sir Crispalot

5

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

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

有没有任何框架可以完成这个任务?NUnit?还是Moq?或者应该由用户来检查? - Arjun K R

2

要检查您的类是否包含任何为null的属性:

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

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

1

你可以随时像这样初始化你的类

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文件设置的,但我想确保所有成员都不为空或空字符串。 - TheBoubou
在这种情况下,我会调用一个辅助方法,例如:string name = myHelper.CheckNode(xmlNode); 在这个辅助方法中,我会检查它是否为 null 或者进行其他的检查。我可以轻松地调整辅助方法,并使其适用于所有元素,你还可以扩展它以支持不仅是 string 类型,而且还有其他所有数据类型。 - balexandre

0
如果类中有许多属性,处理的一种方式是将它们存储在集合中,例如数组或字典,而不是将每个属性声明为类的单独成员。
然后,您可以通过键访问字典中的数据,这与访问类的属性一样容易。优点是您可以循环遍历字典并检查所有属性。

0
我建议在你的类中创建一个函数,检查所有属性的String.IsNullOrEmpty(MyProp1)等。这样,您至少已经将所有检查功能集中在一个地方。并且每当您添加新属性时,您只需要修改这个地方即可。

只是我不想一个一个地检查。 - TheBoubou
除非你想创建一个函数来循环遍历类中的所有成员(例如这里描述的https://dev59.com/A3RB5IYBdhLWcg3wF0HH),否则你必须以某种方式完成此操作。只要你为其创建一个函数,你就只需要执行一次...反射是一个更通用的解决方案,手动检查每个属性创建自己的函数可以获得更好的性能(并提供更多的控制)。 - Julian

0
通过使用基于属性的编程,您可以实现这一点。在这种方法中,您需要在类成员上放置属性,并进行验证。您还可以使用Microsoft Enterprise Library来实现此目的。

0

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

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


0

可能最好的方法是:

将您的属性重构为字符串字典形式。通过循环遍历字典,使用string.IsNullOrEmpty()测试字符串。您可以通过一个单一的索引器属性来替换N个getter/setter,该属性基于键从字典直接设置和检索字符串。


-1

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接