【问题标题】:How to filter list of classes by property name?如何按属性名称过滤类列表?
【发布时间】:2017-05-18 15:49:16
【问题描述】:

我想通过属性名称过滤一个类的集合作为一个字符串。假设我有一个名为 Person 的类,我有一个它的集合,IEnumerable 或 List,我想过滤这个集合,但我不知道确切的过滤器,我的意思是我不能使用:

person.Where(x => x.Id == 1);

让我举个例子。

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int YearOfBorn {get; set;}    
}

现在我创建了一个像这样的集合:

List<Person> p = new List<Person>();

现在我想过滤所有叫 Alex 的人,但我想用这个函数过滤:

public List<Person> Filter(string propertyName, string filterValue, List<Person> persons)

如果我想使用 Linq 或 Lambda,我该如何过滤它?

谢谢

【问题讨论】:

  • 为什么不能使用Where
  • 您是要我们为您编写整个代码吗?
  • 我知道我可以使用 Func 来做到这一点,但我不知道怎么做?而且我知道我必须以某种方式找到属性的类型,但当它是类列表时,我也不知道如何。
  • 如果你想拥有一个像你描述的那样的方法,就像传递属性和属性值的参数一样,你必须使用反射。但你为什么要这样做?您是否正在尝试将 SQL 查询转换为 linq 之类的操作?
  • this answer 也应该有帮助。

标签: c# linq lambda


【解决方案1】:

从技术上讲,您可以尝试使用 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();
}

【讨论】:

  • 我用错了。谢谢。这条线对我帮助很大。 typeof(T).GetProperty(propertyName);
  • @Amir:不客气! Reflection 有时会帮助我们,但要小心:它可能会很慢。
猜你喜欢
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多