【问题标题】:Query data from List<dynamic> which have Multiple type objects从 List<dynamic> 查询具有多种类型对象的数据
【发布时间】:2015-11-17 04:49:44
【问题描述】:
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);

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

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");

这工作没有任何错误。

【问题讨论】:

    标签: .net linq c#-4.0 dynamic


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 当我在列表中有具有位置属性的动态对象时,LINQ 可以正常工作。如果我忘记了 LINQ,那么有性能问题的替代方案是什么
    • 我已经更新了我的答案,以说明您的其他替代方案与性能问题。显然,既然您选择了使用 dynamic 类型,那么您在设计上就已经存在这样的性能问题,所以我的图解解决方案不会对您产生太大影响。
    【解决方案2】:

    您使用的方法很混乱。起初,您不恰当地使用匿名类型。此外,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");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 2013-01-03
      • 2021-12-29
      • 2023-01-08
      • 2020-05-19
      相关资源
      最近更新 更多