简体   繁体   English

C# 查找符合特定条件的对象的属性

[英]C# Find Object's Properties that match a certain criteria

Assume for a moment you have this class:假设你有这个 class:

 // this is c# btw class Rewards { public int property1 {get;set;} public int property2 {get;set;} public int property3 {get;set;} }

and you created an Instance of that class somewhere and updated some of it's values并且您在某处创建了该 class 的实例并更新了它的一些值

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

Now, what you wanna do is get the Name of the properties whose values match a certain criteria (For example: A property where the value is bigger than 0 -> in this case Property1 would be returned / pushed into array现在,您要做的是获取其值与特定条件匹配的属性的名称(例如:值大于 0 的属性 -> 在这种情况下Property1将被返回/推入数组

How would you go about that?你会怎么想呢?

My Attempt:我的尝试:

 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

So what it should do is iterate over each property, run a certain criteria, and store that property in a list if it passed the test所以它应该做的是迭代每个属性,运行某个标准,如果它通过测试,则将该属性存储在一个列表中

I get it I can iterate over the list with a for loop, but I want a solution with a Where query我明白了,我可以使用 for 循环遍历列表,但我想要一个带有 Where 查询的解决方案

You can do this: (also, I would suggest keep the class name as singular like Reward and list of reward as Rewards etc..)您可以这样做:(另外,我建议将 class 名称保留为单数,如 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();

I would do something like this:我会做这样的事情:

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;

You can get all properties by GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance) and use Where to store specific property in records您可以通过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));
}

I like using extension methods for this sort of thing.我喜欢对这类事情使用扩展方法。

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

With this extension method defined, you can get your answer with:定义此扩展方法后,您可以通过以下方式获得答案:

var names = reward.PropertyNamesWhereValue((int pv) => pv > 0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM