2008-12-05 148 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; } 

}