【问题标题】:Finding an item in a list of anonymous objects in C#在 C# 中的匿名对象列表中查找项目
【发布时间】:2013-05-07 14:11:45
【问题描述】:

我有一个匿名对象列表:

var jobs = new List<object>
               {
                 new
                 {
                   JobName = "Job1",
                   JobDate = "Date1",
                   JobUser = "User1"
                 },
                 new
                 {
                   JobName = "Job2",
                   JobDate = "Date2",
                   JobUser = "User2"
                 }
               };

如何使用 linq 找到“Job2”?

例如

var job2 = jobs.Where(x=>x.JobName == "Job2");

我知道以下内容,但无法以优雅的方式将其应用于上面的用例:

var anonymJob = new 
                {
                  JobName = "Job2",
                  JobDate = "Date2",
                  JobUser = "User2"
                };

dynamic tJob = anonymJob.GetType();
string jobName = tJob.JobName; // this will be "Job2"

请注意,jobs.First() 或 Last() 不被接受,因为此问题的正确答案是如何根据其特定属性找到工作。

谢谢

【问题讨论】:

    标签: c# linq anonymous-objects


    【解决方案1】:

    将其设为List&lt;dynamic&gt; 而不是List&lt;object&gt;

    然后你就可以使用普通的 LINQ 查询了。

    【讨论】:

    • 这正是我想要的。非常感谢:-)
    • @MaYaN 这不太可能是您想要依赖的实际解决方案。您使用此解决方案打破了所有静态类型和编译时间检查。匿名对象旨在与类型推断方法结合使用,以便您可以维护程序的编译时验证,如 Jon 的回答所示。
    • @Servy 我同意你的看法。它更像是一个快速修复让它工作。
    • @Dirk 如果你知道这是一个不恰当的解决问题的方法,并且有一个更合适和可取的解决方案,那么你为什么要发布这个。显然,OP 无法意识到这不是一个好的解决方案,或者合适的解决方案是什么,所以发布这个是完全不负责任的。
    • 这几乎是不合适的,它只是不是最好的解决方案,我在发布它时没有想到匿名数组。
    【解决方案2】:

    您可以在查询中使用dynamic

    var job2 = jobs.Where(x => ((dynamic)x).JobName == "Job2");
    

    【讨论】:

    • 这也是可以接受的,但是您能否将它(在性能方面)与 Dirk 的解决方案进行比较?
    • @MaYaN:不,我不能。不知道有没有区别。
    【解决方案3】:

    使用List&lt;dynamic&gt; 代替List&lt;object&gt;

    将其粘贴到 LINQPad 中查看:

    var jobs = new List<dynamic>
                   {
                     new
                     {
                       JobName = "Job1",
                       JobDate = "Date1",
                       JobUser = "User1"
                     },
                     new
                     {
                       JobName = "Job2",
                       JobDate = "Date2",
                       JobUser = "User2"
                     }
                   };
    
    jobs.Where(x=>x.JobName == "Job2").Dump();
    

    【讨论】:

      【解决方案4】:

      如果您使用相同的方法,您可以只使用匿名类型的列表:

      var jobs = new [] {
          new { JobName = "Job1", JobDate = "Date1", JobUser = "User1" },
          new { JobName = "Job2", JobDate = "Date2", JobUser = "User2" }
      }.ToList();
      
      var job2 = jobs.First(x => x.JobName == "Job2");
      

      隐式类型数组的使用允许您的列表仍然是强类型的,但使用匿名类型。

      如果您必须使用List&lt;object&gt;,那么我希望:

      IEnumerable<dynamic> dynamicJobs = jobs;
      var job2 = dynamicJobs.First(x => x.JobName == "Job2");
      

      工作。请注意,这根本不涉及复制列表或更改列表的声明类型。你也可以使用:

      var job2 = jobs.Cast<dynamic>().First(x => x.JobName == "Job2");
      

      【讨论】:

      • @MaYaN:我的回答并没有说明知道工作在列表中的位置。它只是找到与谓词匹配的第一个作业。如果要查找 多个 匹配项,请使用 Where 而不是 First
      • @MaYaN:请注意,使用dynamic 的解决方案确实 动态的 - 所以如果您在JobName 中有错字,编译器不会为您找到它.这与我回答的第二部分类似,但如果您要在相同的方法中搜索,则使用匿名类型的强类型列表的版本更适合 IMO。
      猜你喜欢
      • 2014-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多