从具有多个类型对象的列表<dynamic>中查询数据

Query data from List<dynamic> which have Multiple type objects

var student1 = new {name: "abc"};
var student2 = new {name: "efg"}
var department1 = new { name: "science", location= "ny"}
var department2 = new { name: "maths", location= "nj"}
var department3 = new { name: "social", location= "ny"}

List<dynamic> dynamicList = new List<dynamic>();

dynamicList.Add(student1);
dynamicList.Add(student2);
dynamicList.Add(department1);
dynamicList.Add(department2);
dynamicList.Add(department3);

现在我想获取 dynamicList 中的对象总数,其中 location = "ny"

var total = dynamicList.Count(x=> (string)x.location == "ny");

这是抛出异常,因为没有位置定义。


更新: 当我有位置时,相同的 LINQ 查询有效 属性 对象首先出现在列表中。

    dynamicList.Add(department1);
    dynamicList.Add(department2);
    dynamicList.Add(department3);
    dynamicList.Add(student1);
    dynamicList.Add(student2);
 var total = dynamicList.Count(x=> (string)x.location == "ny");

这没有任何错误。

如果您使用 dynamic 类型,您可以完全忘记 LINQ 和强类型。 LINQ 的全部要点是您正在处理的类型在编译时是已知的。

为了测试动态类型是否定义了一些 属性,您需要 trycatch,这显然会带来相应的性能影响:

var total = dynamicList.Count(x =>
{
    try
    {
        return (string)x.location == "ny";
    }
    catch (RuntimeBinderException)
    {
        return false;
    }
});

也就是说,如果您在代码中使用动态类型,您可能已经习惯了这种对代码性能的影响,所以这没什么大不了的。

您使用的方法很乱。起初你不恰当地使用匿名类型。此外,发明 LINQ 是为了处理泛型类型,即应该在编译时知道类型参数以获得 LINQ 的好处。 无论如何,你可以利用匿名类型的特性,它们的类型由 属性 名称、类型和顺序决定。因此,

的类型
new { name = "", location= ""}

对象与您的 department 对象的类型相同。

这是您可以使用的代码:

List<dynamic> dynamicList = new List<dynamic>
{
    new {name = "abc"},
    new {name = "efg"},
    new {name = "science", location= "ny"},
    new {name = "maths", location= "nj"},
    new {name = "social", location= "ny"},
};
var type = (new {name = "", location = ""}).GetType();
var methodInfo = typeof(Enumerable).GetMethod("OfType");
var genericMethod = methodInfo.MakeGenericMethod(type);
var total = (genericMethod.Invoke(null, new [] {dynamicList}) as IEnumerable<dynamic>)
            .Count(f => f.location == "ny");