gpt4 book ai didi

c# - 在 IEnumerable 上使用 LINQ 时出现编译器错误,但如果先将其转换为 IEnumerable 则不会

转载 作者:太空狗 更新时间:2023-10-30 01:17:47 30 4
gpt4 key购买 nike

好的,所以我正在编写一些非常困惑的代码,因为我正在使用的库正在返回动态类型层次结构。其中一些类型可以展开为动态类型列表,并使我能够在 LINQ 中使用这些动态对象层次结构,我编写了一个小方法,基本上将一些动态对象转换为 IEnumerable

我有一个返回 IEnumerable 的方法,但是当我尝试将它与 LINQ 一起使用时,我收到错误消息“不能将 lambda 表达式用作动态调度操作的参数,而无需先将其转换为委托(delegate)或表达式树类型。”,但是,如果我将方法返回值从 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.";
}

最佳答案

Foo(unknown) 的结果是dynamic , 不是 IEnumerable<dynamic> .那是因为调用了Foo动态解析为 unknowndynamic .

解决Foo静态地,你可以写object unknown = new ExpandoObject(); ,或将调用更改为 Foo((object) unknown) .

更糟糕的是 dynamic 不支持扩展方法. IEnumerable<T> 上的扩展方法即使 T 也可以静态找到是dynamic , 但 C# 编译器不提供事件列表 using命名空间,所以如果你有普通的 dynamic ,运行时不知道要在哪些类中搜索扩展方法。即使.Select(value => value)可以编译,也许把它变成Func<dynamic, dynamic> projection = value => value;然后 unknown.Select(projection) (未经测试),它仍然会在运行时抛出异常。你需要明确地写 Enumerable.Select(unknown, projection)使其发挥作用。

关于c# - 在 IEnumerable<dynamic> 上使用 LINQ 时出现编译器错误,但如果先将其转换为 IEnumerable<dynamic> 则不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30384493/

30 4 0