使用foreach(...)语法,同时在循环内增加索引变量

时间:2008-11-12 13:41:20

标签: c# .net syntax loops for-loop

在查看C#代码时,我经常会看到这样的模式:

DataType[] items = GetSomeItems();
OtherDataType[] itemProps = new OtherDataType[items.Length];

int i = 0;
foreach (DataType item in items)
{
    // Do some stuff with item, then finally
    itemProps[i] = item.Prop;
    i++;
}

for循环迭代items中的对象,但也保留一个计数器(i)以便迭代itemProps。我个人不喜欢这种额外的i,而是可能会做类似的事情:

DataType[] items = GetSomeItems();
OtherDataType[] itemProps = new OtherDataType[items.Length];

for (int i = 0; i < items.Length; i++)
{
    // Do some stuff with items[i], then finally
    itemProps[i] = items[i].Prop;
}

对于我不知道的第一种方法,是否有一些好处?这是每个人都试图使用那种花哨的foreach (...)语法的结果吗?我对你的意见感兴趣。

7 个答案:

答案 0 :(得分:7)

如果您使用的C#3.0会更好;

OtherDataType[] itemProps = items.Select(i=>i.Prop).ToArray();

答案 1 :(得分:4)

当i在数组之外时,如果在循环完成后可用。如果你想计算项目数量而且集合没有提供.Count或.UBound属性,那么这可能很有用。

和我一样,我通常会使用第二种方法,对我来说看起来更干净。

答案 2 :(得分:2)

在这种情况下,我不这么认为。但有时,该集合不实现this[int index],但它确实实现了GetEnumerator()。在后一种情况下,你没有太多选择。

答案 3 :(得分:1)

某些数据结构不适合随机访问,但可以非常快速地迭代(树,链表等)。因此,如果您需要迭代其中一个但由于某种原因需要计数,那么您注定要走得很丑......

答案 4 :(得分:1)

从语义上讲,它们可能是等价的,但实际上使用foreach而不是枚举器可以为编译器提供更多的优化范围。

我不记得所有的争论,但它们在 Effective C#中有很好的涵盖,建议阅读。

答案 5 :(得分:1)

foreach(项目中的DataType项) 这个foreach循环清楚地表明你正在迭代所有DataType项,以及是的。也许它使代码更长一点,但它不是一个“坏”的代码。对于其他for循环,您需要检查括号内部以了解此循环的用途。

这个例子的问题在于你在同一时间迭代两个不同的数组,我们不经常这样做..所以我们陷入两种策略之间......或者我们“破解了一下“你称之为幻想,或者我们回到过去不那么喜欢的东西(int i = 0;我...)。 (当然还有其他两种方式)

所以,我认为这是Vim vs Emacs在你的问题中回归的问题与For vs Foreach循环:)喜欢for()的人会说这个foreach没用,可能会导致性能问题而且很大。喜欢foreach的人会说出类似的话,如果我们能够阅读代码并轻松维护,我们不在乎是否有两条额外的行。

最后,我在第一个例子的第一个范围之外,在第二个范围内的第二个...原因是什么?!因为如果你在你的foreach之外使用我,我会以不同的方式打电话。而且,就我而言,我更喜欢foreach方式,因为你会立即看到正在发生的事情。你也不必考虑它是否&lt;或=。你立即知道你正在迭代所有的列表,然而,遗憾的是,人们会忘记最后的i ++:D所以,我说Vim!

答案 6 :(得分:1)

不要忘记某些集合没有实现直接访问运算符[],并且必须使用最容易使用foreach()访问的IEnumerable接口进行迭代。