无法弄清楚这个(Statement)Lambda Expression

时间:2013-07-13 10:27:57

标签: c# c#-4.0 lambda

我遇到了一段我无法弄清楚的代码,甚至可能无效。您可以在下面找到代码。

我试图在上下文中找出代码

方法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表达式可以是string类型吗?
  • 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>

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

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

这个假设是否正确?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

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

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

第二个是等效的。

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

lambda可以产生一个字符串,但这取决于你使用它的方式(类型推断在这里是一个很大的事情,而且lambdas非常简洁的原因之一)。

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