【问题标题】:query a list of dynamic objects for a FirstOrDefault查询 FirstOrDefault 的动态对象列表
【发布时间】:2012-01-23 21:10:50
【问题描述】:

以下代码将返回一个动态对象的 Enumerable。

protected override dynamic Get(int id)
{ 
    Func<dynamic, bool> check = x => x.ID == id;
    return  Enumerable.Where<dynamic>(this.Get(), check);
}

如何选择 FirstOrDefault 使其成为单个对象而不是 Enumerable?

类似于this answer,但只需要 SingleOrDefault。

【问题讨论】:

    标签: c# linq dynamic .net-4.0 lambda


    【解决方案1】:

    您可以将代码与FirstOrDefault 一起使用,而不是Where。像这样:

    protected override dynamic Get(int id)
    { 
        Func<dynamic, bool> check = x => x.ID == id;
        return Enumerable.FirstOrDefault<dynamic>(this.Get(), check);
    }
    

    【讨论】:

    • 为什么是 Func 步骤?旧 DLR 的解决方法?
    • 因为我们查询的是动态列表所以没有这样的x.ID
    • @eiu165 如果您在下面查看我的答案,它可以在 .NET 4.0 (VS2010) 上编译并运行良好,并且不使用 Func。
    • @JoachimIsaksson,您是否考虑过 Get() 方法的输出是动态的,因此 DLR 无法将类型与扩展方法匹配。据我所知,扩展方法是在编译时解析的,它们依赖于使用语句和对象类型。
    【解决方案2】:

    最简单的方法可能是

    protected override dynamic Get(int id)
    { 
        return Get().FirstOrDefault(x=>x.ID==id);
    }
    

    由于有些人在完成这项工作时遇到了麻烦,因此只需执行一个新的 .NET 4.0 控制台项目(如果您从 3.5 转换,则需要添加 System.Core 和 Microsoft.CSharp 引用)并将其粘贴到 Program 中。 CS。在我测试过的 3 台机器上编译和运行都没有问题。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Dynamic;
    
    namespace ConsoleApplication1
    {
        internal class Program
        {
            protected dynamic Get2(int id)
            {
                Func<dynamic, bool> check = x => x.ID == id;
                return Enumerable.FirstOrDefault<dynamic>(this.Get(), check);
            }
    
            protected dynamic Get(int id)
            {
                return Get().FirstOrDefault(x => x.ID == id);
            }
    
            internal IEnumerable<dynamic> Get()
            {
                dynamic a = new ExpandoObject(); a.ID = 1;
                dynamic b = new ExpandoObject(); b.ID = 2;
                dynamic c = new ExpandoObject(); c.ID = 3;
                return new[] { a, b, c };
            }
    
            static void Main(string[] args)
            {
                var program = new Program();
                Console.WriteLine(program.Get(2).ID);
                Console.WriteLine(program.Get2(2).ID);
            }
    
        }
    
    }
    

    【讨论】:

    • 我收到一个编译时错误“不能使用 lambda 表达式作为动态分派操作的参数,除非先将其转换为委托或表达式树类型”
    • @eui165 我猜你没有运行.NET 4.0?正如我在上面接受的答案中所问的那样,Func 可能是旧 DLR 的一种解决方法。
    • 我可能完全不在这里,我喜欢你的答案写得更好的方式。但我正在查看项目的属性,目标框架是 .net Framework 4。但我仍然收到编译时错误。
    • @eiu165 将测试程序粘贴到答案中,编译并在我的 3 台机器上运行没有问题。你遇到了什么错误?
    • 效果很棒,看起来很棒,易于使用。我需要包括使用 System.Linq;
    【解决方案3】:

    就这样吗?

    protected override dynamic Get(int id)
    { 
        Func<dynamic, bool> check = x => x.ID == id;
        return Enumerable.Where<dynamic>(this.Get(), check).FirstOrDefault();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多