[英]How to filter list of classes by property name?
I want to filter a collection of classes by the property name as a string. 我想通过属性名称将一个类的集合过滤为一个字符串。 Let's say I have a class named Person, and I have a collection of it, either IEnumerable, or List, and I want to filter this collection, but I don't know the exact filter, I mean I can't use: 假设我有一个名为Person的类,并且有它的集合,即IEnumerable或List,我想过滤该集合,但我不知道确切的过滤器,我不能使用:
person.Where(x => x.Id == 1);
Let me give an example. 让我举个例子吧。
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int YearOfBorn {get; set;}
}
And now I create a collection like: 现在,我创建一个像这样的集合:
List<Person> p = new List<Person>();
Now I want to filter everyone whose name is Alex, but I want to filter it using this function: 现在,我想过滤名称为Alex的每个人,但是我想使用以下函数对其进行过滤:
public List<Person> Filter(string propertyName, string filterValue, List<Person> persons)
So how I can filter it if I want to use Linq, or Lambda? 那么,如果我想使用Linq或Lambda,该如何过滤呢?
Thanks 谢谢
Technically, you can try using Reflection : 从技术上讲,您可以尝试使用Reflection :
using System.Reflection;
...
// T, IEnumerable<T> - let's generalize it a bit
public List<T> Filter<T>(string propertyName, string filterValue, IEnumerable<T> persons) {
if (null == persons)
throw new ArgumentNullException("persons");
else if (null == propertyName)
throw new ArgumentNullException("propertyName");
PropertyInfo info = typeof(T).GetProperty(propertyName);
if (null == info)
throw new ArgumentException($"Property {propertyName} hasn't been found.",
"propertyName");
// A bit complex, but in general case we have to think of
// 1. GetValue can be expensive, that's why we ensure it calls just once
// 2. GetValue as well as filterValue can be null
return persons
.Select(item => new {
value = item,
prop = info.GetValue(item),
})
.Where(item => null == filterValue
? item.prop == null
: item.prop != null && string.Equals(filterValue, item.prop.ToString()))
.Select(item => item.value)
.ToList();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.