【问题标题】:Cannot use a lambda expression as an argument to a dynamically dispatched operation不能将 lambda 表达式用作动态分派操作的参数
【发布时间】:2015-04-20 17:04:32
【问题描述】:

我正在尝试执行以下操作

int myObject = getValues(someVar).Sum(x => Int32.Parse(x.Price))

函数如下所示:

List<dynamic> getValues(string something) {...}

这是我收到的错误: “不能将 lambda 表达式用作动态分派操作的参数”

如何在类似于 LINQ SUM 的链式调用中对 List 对象的值求和?

【问题讨论】:

  • 请注意,您的问题与列表无关。您遇到了这个问题,因为您正在使用dynamic 的列表。
  • 有没有办法在类似 LINQ SUM 的链式调用中对动态列表求和?
  • 这个小提琴不起作用,但如果你在 IDE 中复制粘贴相同的东西,它对我来说就很好。 https://dotnetfiddle.net/O22wlB
  • 你能提供getValues吗?
  • 在下面回答,但我还不能接受自己的回答

标签: c# linq dynamic lambda


【解决方案1】:

您的代码有效。您遇到的问题不在您发布的代码中。此代码运行。

void Main() {
    int myObject = getValues("12").Sum(x => Int32.Parse(x.Price));
    Console.WriteLine (myObject);
}

List<dynamic> getValues(string something) {
    var item = new { Price = something };
    IEnumerable<dynamic> items = Enumerable.Repeat<dynamic>(item, 2);
    return items.ToList();
}

这会产生输出24。这个问题可能与类型推断有关,但这只是一个猜测。您应该包含足够的代码来重现错误以获得更可靠的答案。

【讨论】:

  • 奇怪我的代码设置几乎相同,但我收到错误“CS1977:无法使用 lambda 表达式作为动态调度操作的参数,而无需先将其转换为委托或表达式树类型”。这是一个网络表单项目/.net 4.5
  • 您发布的代码中的参数中只有 lambda 表达式是对 .Sum() 的调用。但我不认为这是动态调度的。为了让任何人帮助您,您需要提供足够的信息来重现问题。将您的代码从应用程序的上下文中取出,并将其减少到创建错误所需的最低限度。事实上,我们只是在猜测。
【解决方案2】:

正如评论中提到的,这段代码对我来说很好用:-

public static void Main()
{
     var result = GetData("test").Sum(x => int.Parse(x.Name));
     Console.WriteLine(result);
}

    public static List<dynamic> GetData(string x)
     {
         List<dynamic> data = new List<dynamic>
         {
             new { Id =1, Name ="1"},
             new { Id =2, Name ="4"},
             new { Id =3, Name ="5"}
         };
         return data;
     }

我得到10 作为输出。

【讨论】:

  • 奇怪我的代码设置几乎相同,但我收到错误“CS1977:无法使用 lambda 表达式作为动态调度操作的参数,而无需先将其转换为委托或表达式树类型”。这是一个网络表单项目/.net 4.5
  • 请不要这样发送垃圾邮件 - 您可以随时编辑您的问题
  • @Rahul Singh,我猜这段代码的 fiddle 会引发异常,因为 - 正如 here 所解释的那样 - 匿名类型由编译器创建为 internal,所以可能某些 DotNetFiddle 程序集不能访问它们。如果仍然想使用这个小提琴,他将不得不使用一些非常丑陋的反射技巧(我添加了一些其他用法):https://dotnetfiddle.net/CX0HtS
【解决方案3】:

所以最终发现问题是我将动态变量传递给函数调用,然后使用 LINQ/lambda。似乎这是一个编译器禁止...

dynamic someVar = new {a=1,b=2};

int myObject = getValues(someVar.a).Sum(x => Int32.Parse(x.Price))

【讨论】:

  • 如果您将var someVar 替换为dynamic someVar,那么这作为一种解释是有意义的。尽管如此,var 不足以解释编译器错误。
  • 但这似乎仍然不是一个答案 - 为什么不直接将它添加到您的问题中呢?
  • 我对你的诚实建议是: 1. 不要使用动态 - C# 有一个足够好的类型系统,你应该很少需要它(在这种情况下肯定不是)。 2. 使用调试器 3. 阅读此处的常见问题解答/帮助,了解如何提问
【解决方案4】:

您的getValues 方法返回的是dynamic,而不是List&lt;dynamic&gt;。要么更改您的方法签名,要么根据其结果构造一个new List&lt;dynamic&gt;(...)

dynamic list = new [] {new{Price = "1"},new{Price = "2"}};

// This produces the error you're describing:
Console.WriteLine(list.Sum(x => Int32.Parse(x.Price)));

// This works.
Console.WriteLine(new List<dynamic>(list).Sum(x => Int32.Parse(x.Price)));

【讨论】:

  • 但返回类型在我看来是 List:- List&lt;dynamic&gt; getValues
  • @RahulSingh:是的,在 OP 中看起来是这样,但您假设 OP 按原样正确发布了他的代码。我在字里行间阅读,我很确定我是对的。
  • 我不是 OP :D 也不是反对者,不过分析得很好。
  • 它是返回列表。奇怪的是,我收到错误“CS1977:不能使用 lambda 表达式作为动态调度操作的参数,而无需先将其转换为委托或表达式树类型”
  • @user1234 请发布您的确切代码,无需编辑,以便我们检查
猜你喜欢
  • 2013-06-09
  • 2017-09-18
  • 2017-10-08
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多