【问题标题】:Unable to figure out this (Statement) Lambda Expression无法弄清楚这个(语句)Lambda 表达式
【发布时间】:2013-07-13 20:50:21
【问题描述】:

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

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

GetDataTableData() 方法返回一个System.Data.DataTableSelect(...) 方法返回一个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

因此,要使 lambda 表达式 (s) =&gt; { return new { s.Index }; } 起作用,基础类型中必须存在 Index 属性。

这个假设正确吗?

关于第一次选择

我如何识别它是 Select() 中的构建或可枚举方法 Enumerable.Select&lt;TSource, TResult&gt;

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

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

这个假设正确吗?

【问题讨论】:

    标签: c# c#-4.0 lambda


    【解决方案1】:

    您使用的SelectIEnumerable.Select&lt;T&gt;,因为AsEnumerable() 的返回值是IEnumerable&lt;T&gt;

    【讨论】:

    • 你是指这一行中的第二个.Select( (s, counter) =&gt; new { s.Index, counter = counter + 1 }); 还是你的意思也是第一个?
    • 都是IEnumerable&lt;T&gt;扩展方法。第一个使用Index 属性将行投射到匿名对象中,第二个附加序列中元素的索引。 count 参数获取迭代的索引(从0N-1)。那么,将 Index 值附加到集合中元素的基于 1 的索引的整个过程是什么。
    • @threeFourOneSixOneThree 哦,我是说第二个。 GetDataTableData() 的返回类型是 DataTable 类型还是继承自 DataTable 的类型?
    • 我不确定 GetDataTableData() 是否完全属于 DataTable 类型。我只知道这个question提供了什么
    • @threeFourOneSixOneThree 由于DataTable 没有实现IEnumerable&lt;T&gt;,如果没有AsEnumerable() 调用将其转换为IEnumerable&lt;T&gt;,我看不到第一个选择工作。转换后,它将作为IEnumerable&lt;T&gt; 通过选择(只要它们有效)传播。至于Index 属性,我也看不出它可能来自哪里。
    【解决方案2】:

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

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

    第二个是等价的。

    两个 lambda 都是 Func&lt;&gt; 代表,具有不同的签名。

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

    lambda 的返回类型取决于您在其中使用它的上下文 - 它可以是委托,但在您的情况下,它不是。虽然 lambda 是一个委托 - 如果它有返回类型,则为 Func&lt;T1, T2, ... Tn, TReturn&gt;,如果没有,则为 Action&lt;T1,T2,..., Tn&gt;

    【讨论】:

    • 据我了解s 表示进入 lambda 表达式的对象,在 lambda 内部创建了一个匿名对象,该对象仅具有索引作为属性。这个 lambda (s) =&gt; { return new { s.Index }; } 是否返回 Func&lt;T, int, TResult&gt; 数据类型?
    • 不,它返回一个TResult 类型的对象,在这种情况下是一个匿名类。 lambda Func&lt;&gt;Action&lt;&gt;
    • 所以我可以解释为var myResult = (s) =&gt; { return new { s.Index }; } 并返回对象myResultTResult 类型,这可能是字符串类型?
    猜你喜欢
    • 1970-01-01
    • 2015-10-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多