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.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:
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?
Thanks
Technically, you can try using 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();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.