2008-12-05 180 views
1

我正在对各种类型进行一些简单的理性验证。目前我正在进行的测试是检查以确保其属性已填充。在这种情况下,填充被定义为非空,长度大于零(如果是字符串)或不等于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()来查找属性是否包含特定值的情况。

在此先感谢。

回答

2

做一个HashSet “exactNames” 与PropertyOne,PropertyTwo等,然后列表 “partialNames” 与ValueOne,ValueTwo等。然后:

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

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

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

请注意,您可以缓存要在每种类型基础上进行验证的属性集,因此您只需要对每种类型进行一次该检查。

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

您可以考虑告诉需要什么样的行动做给他们的属性装饰你的属性。

public class MyClass { 

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

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

}