【问题标题】:C# Find Object's Properties that match a certain criteriaC# 查找符合特定条件的对象的属性
【发布时间】:2020-07-24 20:26:36
【问题描述】:

假设你有这个类:

// this is c# btw

class Rewards {

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

并且您在某处创建了该类的 Instance 并更新了它的一些值

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

现在,您要做的是获取其值符合特定条件的属性的 名称(例如:值大于 0 的属性 -> 在这种情况下 Property1 将被返回/推送到数组中

你会怎么做?

我的尝试:

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

所以它应该做的是遍历每个属性,运行特定条件,如果通过测试,则将该属性存储在列表中

我明白了,我可以使用 for 循环遍历列表,但我想要一个带有 Where 查询的解决方案

【问题讨论】:

    标签: c# linq class reflection properties


    【解决方案1】:

    您可以这样做:(另外,我建议将班级名称保持为单数,如 Reward 和奖励列表作为 Rewards 等。)

    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();
    

    【讨论】:

    • 这看起来不错,但它告诉我它没有 Value 的定义
    【解决方案2】:

    我会这样做:

    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;
    

    【讨论】:

      【解决方案3】:

      您可以通过GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)获取所有属性,并使用Where将特定属性存储在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));
      }
      
      

      【讨论】:

        【解决方案4】:

        我喜欢对这类事情使用扩展方法。

        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);
        

        【讨论】:

          猜你喜欢
          • 2016-11-18
          • 1970-01-01
          • 1970-01-01
          • 2019-10-25
          • 2020-05-30
          • 2016-07-26
          • 2020-12-05
          • 2015-01-08
          • 2016-04-03
          相关资源
          最近更新 更多