【问题标题】:why does this loop do one more iteration?为什么这个循环再做一次迭代?
【发布时间】:2012-01-18 11:33:49
【问题描述】:

有一个存储在数据库中的角色列表,并且模型中只有其中一个。实体框架用于填充模型,但我认为它在这里并不重要。

代码攻击似乎用于迭代这些:

foreach (var role in (new Role[1]).Concat(model.Roles))
{
}

但老实说,我一生都无法理解这段代码在做什么。我所知道的是它循环两次而不是一次。谁能澄清它在做什么?

【问题讨论】:

  • 你为什么要做new?您是否尝试过 var temp = new Role[1]).Concat(model.Roles) 并分析 temp 包含的内容?你 100% 确定 model.Roles 只包含一个对象吗?
  • @ChrisF 不幸的是,这不是我的代码,这就是我问的原因,因为我只是不明白它在做什么。是的,数据库中只显示一个角色。是的,按照您的建议做可能是一个好主意,应该想到这一点! :-)

标签: c# entity-framework


【解决方案1】:

语句new Role[1] 创建一个包含单个元素的数组。该元素是null,除非Role 是我认为不是的值类型。否则就是调用new Role() 得到的结果。

然后将null 角色与model.Roles 中的任何角色连接起来。最终结果是将null 添加到model.Roles 中的角色集合之前。然后迭代这个新集合。

如果model.Roles 包含元素

{ role1, role2, role3 }

您的 foreach 循环将迭代

{ null, role1, role2, role3 }

【讨论】:

  • 谢谢。我现在可以理解它在做什么了。我不知道为什么要这样编程,但他的缺陷现在很明显。
【解决方案2】:

Concat 连接两个序列。它几乎像这样工作:

public static IEnumerable<T> Concat<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
  foreach(T item in first)
    yield return item;
  foreach(T item in second)
    yield return second;
}

(new Role[1]).Concat(model.Roles) 因此创建一个包含一个Role (new Role[1]) 的数组,无论model.Roles 中的内容是什么,然后返回第一个后跟第二个的序列,这是一个默认Role(如果Role 是一个引用类型),然后是所有的model.Roles

【讨论】:

  • 感谢您的回答。我会接受 Martin 的回答,因为它看起来像是先完成的,但是已经 +1 给了你很好的答案
  • 当两个答案对您来说都一样好时,这总是一个好方法。
【解决方案3】:

调用 Concat 会在两个数组上创建一个迭代器。所以 2 个查询。

【讨论】: