C# 在IEnumerable上使用LINQ时出现编译器错误,但如果先将其强制转换为IEnumerable,则不会出现此错误
好的,我正在编写一些非常混乱的代码,因为我使用的库正在返回动态类型层次结构。其中一些类型可以展开为动态类型列表,为了使我能够在LINQ中使用这些动态对象层次结构,我编写了一个基本上将一些动态对象转换为IEnumerable的小方法 我有一个返回IEnumerable的方法,但是当我尝试将它与LINQ一起使用时,我得到一个错误,如果不首先将lambda表达式转换为委托或表达式树类型,就不能将它用作动态调度操作的参数。然而,如果我将方法返回值从IEnumerable转换为IEnumerable,我会认为没有操作,它编译并运行良好 有人能向我解释一下这种行为吗C# 在IEnumerable上使用LINQ时出现编译器错误,但如果先将其强制转换为IEnumerable,则不会出现此错误,c#,linq,dynamic,ienumerable,C#,Linq,Dynamic,Ienumerable,好的,我正在编写一些非常混乱的代码,因为我使用的库正在返回动态类型层次结构。其中一些类型可以展开为动态类型列表,为了使我能够在LINQ中使用这些动态对象层次结构,我编写了一个基本上将一些动态对象转换为IEnumerable的小方法 我有一个返回IEnumerable的方法,但是当我尝试将它与LINQ一起使用时,我得到一个错误,如果不首先将lambda表达式转换为委托或表达式树类型,就不能将它用作动态调度操作的参数。然而,如果我将方法返回值从IEnumerable转换为IEnumerable,我会
void Main()
{
Foo(null).Select(value => value); // OK... I was expecting this to work.
dynamic unknown = new ExpandoObject();
Foo(unknown).Select(value => value); //COMPILER ERROR: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type... this was a bit more unexpected.
((IEnumerable<dynamic>)Foo(unknown)).Select(value => value); // OK... this was really unexpected.
}
IEnumerable<dynamic> Foo(dynamic param)
{
yield return "Tranformation logic from param to IEnumerable of param goes here.";
}
Foounknown的结果是动态的,而不是IEnumerable。这是因为对Foo的调用是动态解析的,因为unknown是动态的
要静态解析Foo,可以编写object unknown=new expandooobject;,或者将调用更改为Fooobject unknown
更糟糕的是,dynamic上不支持扩展方法。即使T是动态的,IEnumerable上的扩展方法也可以静态找到,但是C编译器不提供使用名称空间的活动类列表,因此如果您使用纯动态的,则运行时不知道要搜索哪些类来扩展方法。即使可以编译.Selectvalue=>value,也可以将其转换为Func projection=value=>value;然后未知。如果未测试Selectprojection,它仍会在运行时引发异常。您需要显式地编写可枚举项。选择Unknown和projection以使其工作