C# 为FirstOrDefault查询动态对象列表

C# 为FirstOrDefault查询动态对象列表,c#,linq,dynamic,.net-4.0,lambda,C#,Linq,Dynamic,.net 4.0,Lambda,以下代码将返回可枚举的动态对象 protected override dynamic Get(int id) { Func<dynamic, bool> check = x => x.ID == id; return Enumerable.Where<dynamic>(this.Get(), check); } protected override动态Get(int-id) { Func check=x=>x.ID==ID; 返回可枚举的.W

以下代码将返回可枚举的动态对象

protected override dynamic Get(int id)
{ 
    Func<dynamic, bool> check = x => x.ID == id;
    return  Enumerable.Where<dynamic>(this.Get(), check);
}
protected override动态Get(int-id)
{ 
Func check=x=>x.ID==ID;
返回可枚举的.Where(this.Get(),check);
}
如何选择第一个或默认值,使其成为单个对象而不是可枚举对象

类似于但只需要SingleOrDefault

就这样

protected override dynamic Get(int id)
{ 
    Func<dynamic, bool> check = x => x.ID == id;
    return Enumerable.Where<dynamic>(this.Get(), check).FirstOrDefault();
}
protected override动态Get(int-id)
{ 
Func check=x=>x.ID==ID;
返回可枚举的.Where(this.Get(),check.FirstOrDefault();
}

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

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

最简单的方法可能是

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

    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
运用系统动力学;
命名空间控制台应用程序1
{
内部课程计划
{
受保护的动态Get2(int-id)
{
Func check=x=>x.ID==ID;
返回Enumerable.FirstOrDefault(this.Get(),check);
}
受保护的动态Get(int-id)
{
返回Get().FirstOrDefault(x=>x.ID==ID);
}
内部IEnumerable Get()
{
动态a=新的ExpandooObject();a.ID=1;
动态b=新的ExpandooObject();b.ID=2;
动态c=新的ExpandooObject();c.ID=3;
返回新的[]{a,b,c};
}
静态void Main(字符串[]参数)
{
var program=新程序();
Console.WriteLine(program.Get(2.ID));
Console.WriteLine(program.Get2(2.ID));
}
}
}

为什么选择Func步骤?旧DLR的解决方案?因为我们正在查询动态列表,因此没有这样的x。ID@eiu165如果你看我下面的答案,它在.NET 4.0(VS2010)上编译并运行良好,不使用Func。@JoachimIsaksson,你考虑过Get()方法的输出是动态的吗,因此,DLR无法使用扩展方法匹配该类型。据我所知,扩展方法是在编译时解析的,它们依赖于使用语句和对象类型。我得到一个编译时错误“如果不先将lambda表达式转换为委托或表达式树类型,则无法将lambda表达式用作动态调度操作的参数”@eui165我猜你不是在运行.NET4.0吧?正如我在上面接受的答案中所问的,Func可能是旧DLR的一个解决方案。我可能在这里完全不正确,我更喜欢你的答案的书写方式。但我正在研究项目的属性,目标框架是.NETFramework4。但我仍然得到一个编译时错误。@eiu165在答案中粘贴了一个测试程序,在我的3台机器上编译并运行,没有问题。你会犯什么错误?非常棒,看起来很棒,易于使用。我需要包括使用System.Linq;