Фильтрация свойств объектов по имени

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

Заранее спасибо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
353
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Сделайте 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; }

}

Другие вопросы по теме