Я провожу простую проверку работоспособности для разных типов. Текущий тест, над которым я работаю, проверяет, заполнены ли их свойства. В этом случае заполненный определяется как ненулевое, имеющее длину больше нуля (если строка) или не равную 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 на самом деле работает хуже, чем отражение (а не то, что отражение быстро вспыхивает). Есть ли более эффективный способ отфильтровать свойства нескольких разных типов?
Я думал о массивном регулярном выражении, но я не уверен, как его отформатировать, к тому же, вероятно, оно будет нечитаемым, учитывая его размер. Я также рассматривал возможность сохранения значений в списке, а затем использовать Linq, но я не уверен, как обрабатывать случаи, в которых используется String.IndexOf (), чтобы определить, содержит ли свойство определенное значение.
Заранее спасибо.





Сделайте HashSet «точные имена» с помощью 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
}
(Нечетные отступы, чтобы избежать переноса.)
Обратите внимание, что вы можете кэшировать набор свойств для проверки для каждого типа, поэтому вам нужно пройти эту проверку только один раз для каждого типа.
Ваша идея помогает ускорить мою программу, спасибо. Однако у вас были некоторые проблемы с синтаксисом, плюс вы соответствовали элементам, найденным в списках, и мне нужны были элементы, которых нет в списке. Вот код, который я в итоге использовал.
List<System.Reflection.PropertyInfo> pi = type.GetProperties().ToList();
var matchingProperties = pi.Where( prop => !PropertyExclusionSet.Contains( prop.Name )
&& !PropertiesPartialSet.Any( name => prop.Name.Contains( name ) ) );
Вы можете подумать об украшении своих свойств атрибутами, которые сообщают, какое действие с ними нужно сделать.
public class MyClass {
[CheckMe]
public int PropertyOne { get; set; }
[DontCheckMe]
public int PropertyTwo { get; set; }
}