简体   繁体   English

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

[英]How check whether class members are not null or empty

I have a class with only string members like this : 我有一个只有这样的字符串成员的类:

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

I create an instance : 我创建了一个实例:

Var myClass = new MyClass();

Later in the code, I'd like to know if all the member (MyProp1 and MyProp2) are not null or empty. 稍后在代码中,我想知道所有成员(MyProp1和MyProp2)是否为空或空。 I know I can use a if of course but there is much more properties than 2 in my real code. 我知道我可以使用if当然但在我的实际代码中有更多属性而不是2。

Is there a way to do this ? 有没有办法做到这一点 ?

Thanks, 谢谢,

Using a dictionary based store for your properties is probably the easiest way of doing this: 为您的属性使用基于字典的存储可能是最简单的方法:

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

Another method for doing this would be to compare it with a default instance: 执行此操作的另一种方法是将其与默认实例进行比较:

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

You can try to use the reflect to check the properties. 您可以尝试使用反射来检查属性。 You should need confirm that all the properties are public, and the type is string. 您应该确认所有属性都是公共的,类型是字符串。 Here is the code. 这是代码。

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

To check if your class contains 'any' properties which are null: 要检查您的类是否包含null的“any”属性:

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

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

You can always initialize your class like 您可以随时初始化您的课程

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

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

and, unless your programmatically assign a null value to it, the new MyClass() will always have String.Empty in their 2 properties... 并且,除非您以编程方式为其分配null值,否则new MyClass()将在其2个属性中始终具有String.Empty ...


from comment: 来自评论:

What I do in those cases is call a helper, for example: string name = myHelper.CheckNode(xmlNode); 在这些情况下我做的是调用帮助器,例如:string name = myHelper.CheckNode(xmlNode); and in that helper I check if it's null, any other check, I can easily tweek the helper method and it will be available to all elements, and you can extend it to support not only strings but all other data types as well 并且在那个帮助器中我检查它是否为空,任何其他检查,我可以轻松地调整辅助方法并且它将可用于所有元素,并且您可以扩展它以不仅支持字符串而且支持所有其他数据类型

So, imagine that you are reading nodes from your XML, you write them like: 因此,假设您正在从XML中读取节点,您可以将它们写成:

string name = myHelper.CheckNode(node);

in your helper, you could have something like: 在你的助手中,你可以有类似的东西:

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

your helper then could have a method like: 你的助手然后可以有一个方法,如:

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

or for the variant (Extension Method) 或变体(扩展方法)

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

If there are many properties in the class, one way of handling this is storing them in a collection, such as an array or a dictionary, instead of declaring each property as a separate member of the class. 如果类中有许多属性,则处理此属性的一种方法是将它们存储在集合(如数组或字典)中,而不是将每个属性声明为类的单独成员。

Then you can access data in the dictionary by key, which is as easy as accessing a property of a class. 然后,您可以按键访问字典中的数据,这与访问类的属性一样简单。 And the advantage is that you can loop over the dictionary and check all the properties in a loop. 而且优点是你可以遍历字典并检查循环中的所有属性。

I would suggest creating a function in your class where you check String.IsNullOrEmpty(MyProp1) etc. for all your properties. 我建议在你的类中创建一个函数,在那里检查所有属性的String.IsNullOrEmpty(MyProp1)等。 This way you at least have gathered all the ckecking functionality in a single place. 这样你至少可以在一个地方收集所有的ckecking功能。 And you only have this place to modify whenever you add new properties. 只要添加新属性,您就只能修改此位置。

By using Attribute Base programming you can achieve this. 通过使用Attribute Base编程,您可以实现此目的。 In this approach you will need to place attribute over the class member, and validation is can be done. 在这种方法中,您需要将属性放在类成员上,并且可以进行验证。 You can also use Microsoft Enterprise Library for this. 您也可以使用Microsoft Enterprise Library

To check if all the elements are set you could add a IsEmpty() method to your class that would check the internal properties. 要检查是否已设置所有元素,可以在类中添加一个IsEmpty()方法来检查内部属性。 Then you wouldn't have to duplicate the if statements everywhere trough your code. 然后,您不必通过代码在任何地方复制if语句。

In your IsEmpty() method you can use a regular if statement to check all the fields or you can use reflection to automaticaly retrieve all string properties and check their values. IsEmpty()方法中,您可以使用常规if语句检查所有字段,也可以使用反射自动检索所有字符串属性并检查其值。 The performance of reflection will be worse then a normal if check but if that's not a problem you can reuse the reflection code in all your entities to check their values. 如果检查,反射的性能将比正常情况更糟,但如果这不是问题,您可以在所有实体中重复使用反射代码来检查它们的值。

Probably the best way would be to : 可能最好的方法是:

Restructure your properties in the form of a Dictionary of strings. 以字符串字典的形式重构您的属性。 Loop through the dictionary to test the strings using string.IsNullOrEmpty(). 循环遍历字典以使用string.IsNullOrEmpty()测试字符串。 You could replace the N getter/setters by a single Indexer property which sets and retrieves the strings directly from the dictionary based on a key 你可以用一个Indexer属性替换N getter / setter,它根据一个键直接从字典中设置和检索字符串

You can use try the following style. 您可以尝试使用以下样式。 I haven't tried it before but you might see if it helps 我之前没有尝试过,但你可能会看到它是否有帮助

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM