无法计算此(语句)Lambda表达式

本文关键字:Lambda 表达式 语句 计算 | 更新日期: 2023-09-27 18:22:15

我遇到了一段我无法理解的代码,甚至可能无法工作。你可以在下面找到代码。

我试图在上下文中理解的代码

方法GetDataTableData()返回一个System.Data.DataTable,方法Select(...)返回一个DataRow对象数组:DataRow[] rows。据我所知,Select()中的lambda是无效的。

    var table = GetDataTableData()
                 .Select(s => new { s.Index })
                 .AsEnumerable()
                 .Select(
                     (s, counter) => new { s.Index, counter = counter + 1 }
                 );

我的问题:这个lambda做什么?它有效/有效吗

方法Select(...)有几个重载,它们都以字符串类型开头。

  • lambda表达式的类型可以是字符串吗
  • lambda的返回类型是什么——总是委托

以下是上方有问题的线路

    // of what type is this (a delegate?)
    s => new { s.Index } 
    ... 
    // and what does this
    (s, counter) => new { s.Index, counter = counter + 1 }

阅读以下答案后更新

据我所知,至少第二个Select指的是IEnumerable.Select<T>。但在集合上调用AsEnumerable()不会改变底层类型:

    // calling AsEnumberable() does not change type
    IEnumerable<DataRow> enumDataRows = GetDataTable().AsEnumerable();
    Type type = enumDataRows.GetType().GetGenericArguments()[0]; 
    type.Dump(); // still returns DataRow

因此,属性Index必须存在于lambda表达式(s) => { return new { s.Index }; }的基础类型中才能工作。

这个假设正确吗

关于第一次选择

我如何识别它是Select()中的内部版本或可枚举方法Enumerable.Select<TSource, TResult>

  • IEnumerable<TSource>, Func<TSource, TResult>
  • IEnumerable<TSource>, Func<TSource, Int32, TResult>

尽管如此,我还是认为该语句仍然无效,因为tSource底层对象DataRow没有属性Index:

    var tResult = GetDataTable().Select(
                      (tSource, tResult) => { return new { tSource.Index }; }
                      );

这个假设正确吗

无法计算此(语句)Lambda表达式

您使用的SelectIEnumerable.Select<T>,因为AsEnumerable()的返回值是IEnumerable<T>

两者都是导致匿名对象的lambda。此外,两者都是以非常简洁的形式写成的,完整的形式是:

(s) => { return new { s.Index }; }

第二个是等价的。

两个Lambda都是Func<>代表,具有不同的签名。

lambda可以产生字符串,但这取决于您使用它的目的(类型推理在这里是一件大事,也是lambda非常简洁的原因之一)。

lambda的返回类型取决于您在其中使用它的上下文——它可以是委托,但在您的情况下,它不是。不过,lambda是一个委托——如果它有返回类型,它就是Func<T1, T2, ... Tn, TReturn>,如果没有,它就是Action<T1,T2,..., Tn>