简体   繁体   中英

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.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.

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