按名称过滤对象属性

时间:2008-12-05 16:05:32

标签: c# string properties

我正在对各种类型进行一些简单的健全性验证。我正在进行的当前测试是检查以确保其属性已填充。在这种情况下,填充定义为非null,长度大于零(如果是字符串),或者不等于0(如果是整数)。

此测试的“棘手”部分是某些属性不受此检查的影响。现在我使用一个巨大的if语句来清除不需要检查的属性。

//Gets all the properties of the currect feature.
System.Reflection.PropertyInfo[] pi = t.GetProperties();

for(int i = 0; i < pi.Length; i++)
{
    if(!pi[i].Name.Equals("PropertyOne") 
    && !pi[i].Name.Equals("PropertyTwo") 
    && !pi[i].Name.Equals("PropertyThree") 
            //... repeat a bunch more times
    && !pi[i].Name.IndexOf("ValueOne") != -1 
    && !pi[i].Name.IndexOf("ValueTwo") != -1 
            //... repeat a bunch more times
    {
        //Perform the validation check.
    }                 
}

在分析时,我注意到if语句实际上比反射更差(不是反射速度快)。是否有更有效的方法来过滤几种不同类型的属性?

我已经考虑了一个大规模的正则表达式,但我不确定如何格式化它,加上它的大小可能是不可读的。我还考虑将值存储在List中,然后使用Linq,但我不知道如何处理使用String.IndexOf()来查找属性是否包含特定值的情况。

提前致谢。

3 个答案:

答案 0 :(得分:2)

使用PropertyOne,PropertyTwo等创建一个HashSet“exactNames”,然后使用ValueOne,ValueTwo等创建一个List“partialNames”。然后:

var matchingProperties = pi.Where(exactNames.Contains(pi.Name) ||
                          partialNames.Any(name => pi.Name.Contains(name));

foreach (PropertyInfo property in matchingProperties)
{
    // Stuff
}

(奇怪的缩进只是为了避免包装。)

请注意,您可以缓存一组属性以基于每个类型进行验证,因此您只需要对每种类型进行一次此检查。

答案 1 :(得分:0)

您的想法有助于加快我的计划,谢谢。但是,您有一些语法问题,而且您匹配列表中找到的项目,我需要的项目不在列表中。这是我最终使用的代码。

List<System.Reflection.PropertyInfo> pi = type.GetProperties().ToList();

var matchingProperties = pi.Where( prop => !PropertyExclusionSet.Contains( prop.Name )
&& !PropertiesPartialSet.Any( name => prop.Name.Contains( name ) ) );

答案 2 :(得分:0)

您可以考虑使用属性来装饰您的属性,这些属性可以告诉您需要对它们执行哪些操作。

public class MyClass {

   [CheckMe]
   public int PropertyOne { get; set; }

   [DontCheckMe]
   public int PropertyTwo { get; set; }

}