C# Найти свойства объекта, которые соответствуют определенным критериям - PullRequest
0 голосов
/ 12 апреля 2020

Предположим, у вас есть этот класс:

// this is c# btw

class Rewards {

  public int property1 {get;set;}
  public int property2 {get;set;}
  public int property3 {get;set;}
}

и вы создали где-то экземпляр этого класса и обновили некоторые его значения

Rewards reward = new Rewards();
reward.property1 = 10000000000;

Теперь вам нужно получить Имя свойств, значения которых соответствуют определенным критериям (например, свойство, значение которого равно больше 0 -> в этом случае Property1 будет возвращено / помещено в массив

Как бы вы go об этом?

Моя попытка:

var allRewards = typeof(Rewards).GetProperties().ToList(); // this gets all the properties, but I'm not sure how the filter them with a Where query

Debug.Log(typeof(Rewards).GetProperty(allRewards[1].Name).GetValue(rewards))); // printing one of the values as a test - which works

Поэтому он должен выполнять итерацию по каждому свойству, выполнять определенные критерии и сохранять это свойство в списке, если оно прошло тест

Я понял, что могу перебрать список с помощью для l oop, но мне нужно решение с запросом Where

Ответы [ 4 ]

0 голосов
/ 14 апреля 2020

Мне нравится использовать методы расширения для такого рода вещей.

public static class TypeExt {
    public static IEnumerable<string> PropertyNamesWhereValue<T, TProp>(this T o, Func<TProp, bool> predFn) =>
        typeof(T).GetProperties().Where(p => p.GetValue(o) is TProp pv && predFn(pv)).Select(p => p.Name);
}

С этим определенным методом расширения вы можете получить ответ с помощью:

var names = reward.PropertyNamesWhereValue((int pv) => pv > 0);
0 голосов
/ 12 апреля 2020

Я бы сделал что-то вроде этого:

var allProperties = reward.GetType().GetProperties(BindingFlags.Public);

var result = from pi in allProperties
            where pi.DeclaringType == typeof(int) && (int)pi.GetValue(reward) > 100
            select pi.Name;
0 голосов
/ 12 апреля 2020

Вы можете получить все свойства по GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance) и использовать Where для хранения указанного c свойства в records

List<PropertyInfo> records = rewards.GetType()
     .GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)
     .Where(a => a.PropertyType == typeof(int) && ((int)a.GetValue(rewards)) > 10000)
     .ToList();
foreach (var item in records)
{
    Console.WriteLine(item.Name + " " + item.GetValue(rewards));
}

0 голосов
/ 12 апреля 2020

Вы можете сделать это: (также я бы посоветовал оставить имя класса в единственном числе, например, Награда и список наград, как Награды и т. Д. c ..)

var reward = new Rewards();

var listofFields = typeof(Rewards)
            .GetProperties()
            .Where(prop => prop.DeclaringType == typeof(int) &&
                   (int)prop.GetValue(reward) > someValue)
            .Select(prop => prop.Name)
            .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...