2008-12-05 3 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. 
    }     
} 

При профилировании, я заметил, что если заявление фактически выполняет хуже, чем отражение (не то, что отражение молниеносно). Есть ли более эффективный способ фильтрации свойств нескольких разных типов?

Я думал о массивном регулярном выражении, но я не уверен, как его отформатировать, плюс он, вероятно, будет нечитаемым с учетом его размера. Я также рассмотрел сохранение значений в списке и затем использование 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; } 

}