【问题标题】:C#: using Take() inside foreach is statement is alright to use?C#:在 foreach 中使用 Take() is 语句可以使用吗?
【发布时间】:2017-06-16 09:50:02
【问题描述】:

谁能建议我们应该使用以下两行代码?

foreach(var items in itemList.Take(20))
{

}

var itemList = itemList.Take(20);

foreach(var items in itemList)
{

}

以上两行在优化代码方面有什么不同吗,如果有,请告诉我原因。

【问题讨论】:

  • 吹毛求疵:请注意,您不能在第二个示例中重新声明 itemList,如果 itemList 不是 IEnumerable<T>,但是,比如说,List<T>,那么只需删除 var 即可也不行。然而,这只是一个观察,对我的回答没有影响。
  • 它们是相同的,使用更具可读性的那个,恕我直言,它是第 2 版。
  • 两者同样未优化

标签: c# linq foreach ienumerable ienumerator


【解决方案1】:

不,这两段代码的行为不会有所不同。

事实上,如果你看一下这个SharpLab example,你会注意到这两段代码编译成完全相同的IL。

所以:

  • 代码看起来不同,如果对很重要,请选择您觉得最舒服的代码
  • 代码将编译精确相同的输出(在发布版本中),在这种情况下,代码的外观(在这种情况下)与代码的行为或性能

简而言之,选择您认为最好看的版本。

【讨论】:

  • 个人意见:对于Take(20),我可能会使用前一个示例,但是如果您将Take 替换为Where 或类似的,那么我可能会使用后一个示例,以便能够在 for 循环上放置一个断点并在循环之前检查过滤的集合。
【解决方案2】:

foreach 只对in 关键字之后的方法进行一次评估。一个非常简单的例子,如ConsoleApplication

public class Test
{
    public IEnumerable<int> ReturnAList()
    {
        Console.WriteLine("ReturnAList called");
        return new List<int>()
        {
            1, 1, 2, 3, 5, 8, 13, 21, 34
        };
    }
}

然后:

var test = new Test();
foreach(var t in test.ReturnAList())
{
    Console.WriteLine(t);
}

你会看到输出是:

//  ReturnAList called
//  1
//  1
//  2
//  3
//  5
//  8
//  13
//  21
//  34

【讨论】:

    【解决方案3】:

    感谢您的洞察力。

    但是我已经编写了一个控制台应用程序,第一个示例(直接迭代 Take())在执行过程中比后者消耗更多时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-01
      • 2016-04-03
      • 2017-05-07
      • 1970-01-01
      相关资源
      最近更新 更多