繁体   English   中英

如何过滤列表 <object> 使用Linq / Lambda

[英]How to filter List<object> using Linq/Lambda

这是我的情况

List<object> obj = new List<object>();
obj.Add(new {id = 1, name = "Jakob"});
obj.Add(new {id = 2, name = "Sam"});
obj.Add(new {id = 3, name = "Albert"});
obj.Add(new {id = 1, name = "Jakob"});

您如何像这样过滤List<object>以便返回名称为“ Jakob”的用户列表?

obj.Where(t => t.name == "Jakob")不起作用

如果将对象转换为动态对象,则它应该可以工作:

obj.Where(t => ((dynamic)t).name == "Jakob")

编辑

为了完整起见,我应该提到几件事:

  • 动态类型的使用归结为在其顶部具有反射的对象的使用,因此,如果使用这种方法,最终您将获得比反射更好的东西。
  • 完全使用动态涉及将必要的程序集(又名DLR)加载到CLR中,如果根本不使用动态的话,则不会加载。 换句话说,这是开销。

因此,请自行决定使用。

您最好的选择是声明一个代表用户的类。

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

然后创建User对象列表并查询该列表。

var users = new List<User>
{
    new User { Id = 1,  Name = "Jakob" },
    new User { Id = 2,  Name = "Sam" },
    new User { Id = 3,  Name = "Albert" }
}

var filteredUsers = users.Where(user => user.Name == "Jakob");

否则,您必须依靠Tengiz建议的解决方案。

另一种选择是创建匿名类型的数组,然后通过ToList IEnumerable扩展方法将其转换为列表:

var obj = (new[] {
    new { id = 1, name = "Jakob" },
    new { id = 2, name = "Sam" },
    new { id = 3, name = "Albert" },
    new { id = 1, name = "Jakob" }}).ToList();
obj.Where(c => c.name == "Jakob");

如果您真的不需要列表,数组也很好-那就不要转换为列表。 好处是您获得了强类型化的列表,而不是任意对象的列表。

您可以使用反射

    var l = new List<object>();
    l.Add(new {key = "key1", v = "value1"});
    l.Add(new {key = "key2", v = "value2", v2="another value"});
    l.Add(new {key = "key3", v = "value3", v3= 4});
    l.Add(new {key = "key4", v = "value4", v4 = 5.3});

    var r = l.Where(x=> (string)x.GetType().GetProperty("key")?.GetValue(x) == "key1");

获取元素的类型,然后找到所需的属性。 然后获取当前实例的值,并将其与要过滤的值进行比较。

但是,另一方面,即使List包含几种不同匿名类型的项目(如果它们具有不同的属性),只要它们都具有要过滤的属性,这种方法就可以工作。

编辑

使用c#6可以使用? 运算符,它是对null的内联检查。 即,如果GetProperty()返回null ,因为没有找到该属性,则表达式返回null不执行GetValue()否则会抛出一个NullReferenceException

暂无
暂无

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

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