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

时间:2022-11-21 13:56:12

When looking at C# code, I often see patterns like this:

在查看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++;
}

The for-loop iterates over the objects in items, but also keeping a counter (i) for iterating over itemProps as well. I personally don't like this extra i hanging around, and instead would probably do something like:

for循环遍历项目中的对象,但也保持计数器(i)以迭代itemProps。我个人不喜欢这种额外的闲逛,而是可能做的事情如下:

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;
}

Is there perhaps some benfit to the first approach I'm not aware of? Is this a result of everybody trying to use that fancy foreach (...) syntax? I'm interested in your opinions on this.

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

7 个解决方案

#1


7  

If you are using C# 3.0 that will be better;

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

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

#2


4  

With i being outside the array then if would be available after the completion of the loop. If you wanted to count the number of items and the collection didn't provide a .Count or .UBound property then this could be useful.

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

Like you I would normally use the second method, looks much cleaner to me.

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

#3


2  

In this case, I don't think so. Sometimes, though, the collection doesn't implement this[int index] but it does implement GetEnumerator(). In the latter case, you don't have much choice.

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

#4


1  

Some data structures are not well suited for random access but can be iterated over very fast ( Trees, linked lists, etc ). So if you need to iterate over one of these but need a count for some reason, your doomed to go the ugly way...

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

#5


1  

Semantically they may be equivalent, but in fact using foreach over an enumerator gives the compiler more scope to optimise.

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

I don't remember all the arguments off the top of my head,but they are well covered in Effective C#, which is recommended reading.

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

#6


1  

foreach (DataType item in items) This foreach loop makes it crystal clear that you're iterating over all the DataType item of, well yes, items. Maybe it makes the code a little longer, but it's not a "bad" code. For the other for-loop, you need to check inside the brackets to have an idea for what this loop is used.

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

The problem with this example lies in the fact that you're iterating over two different arrays in the same time which we don't do that often.. so we are stuck between two strategies.. either we "hack a bit" the fancy-foreach as you call it or we get back on the old-not-so-loved for(int i = 0; i ...). (There are other ways than those 2, of course)

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

So, I think it's the Vim vs Emacs things coming back in your question with the For vs Foreach loop :) People who like the for(), will say this foreach is useless, might cause performance issues and is just big. People who prefere foreach will say something like, we don't care if there's two extra line if we can read the code and maintenance it easily.

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

Finally, the i is outside the scope first the first example and inside for the second.. reasons to that?! Because if you use the i outside of your foreach, I would have called differently. And, for my opinion, I prefer the foreach ways because you see immediately what is happening. You also don't have to think about if it's < or =. You know immediately that you are iterating over all the list, However, sadly, people will forget about the i++ at the end :D So, I say Vim!

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

#7


1  

Lets not forget that some collections do not implement a direct access operator[] and that you have to iterate using the IEnumerable interface which is most easily accessed with foreach().

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

#1


7  

If you are using C# 3.0 that will be better;

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

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

#2


4  

With i being outside the array then if would be available after the completion of the loop. If you wanted to count the number of items and the collection didn't provide a .Count or .UBound property then this could be useful.

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

Like you I would normally use the second method, looks much cleaner to me.

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

#3


2  

In this case, I don't think so. Sometimes, though, the collection doesn't implement this[int index] but it does implement GetEnumerator(). In the latter case, you don't have much choice.

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

#4


1  

Some data structures are not well suited for random access but can be iterated over very fast ( Trees, linked lists, etc ). So if you need to iterate over one of these but need a count for some reason, your doomed to go the ugly way...

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

#5


1  

Semantically they may be equivalent, but in fact using foreach over an enumerator gives the compiler more scope to optimise.

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

I don't remember all the arguments off the top of my head,but they are well covered in Effective C#, which is recommended reading.

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

#6


1  

foreach (DataType item in items) This foreach loop makes it crystal clear that you're iterating over all the DataType item of, well yes, items. Maybe it makes the code a little longer, but it's not a "bad" code. For the other for-loop, you need to check inside the brackets to have an idea for what this loop is used.

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

The problem with this example lies in the fact that you're iterating over two different arrays in the same time which we don't do that often.. so we are stuck between two strategies.. either we "hack a bit" the fancy-foreach as you call it or we get back on the old-not-so-loved for(int i = 0; i ...). (There are other ways than those 2, of course)

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

So, I think it's the Vim vs Emacs things coming back in your question with the For vs Foreach loop :) People who like the for(), will say this foreach is useless, might cause performance issues and is just big. People who prefere foreach will say something like, we don't care if there's two extra line if we can read the code and maintenance it easily.

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

Finally, the i is outside the scope first the first example and inside for the second.. reasons to that?! Because if you use the i outside of your foreach, I would have called differently. And, for my opinion, I prefer the foreach ways because you see immediately what is happening. You also don't have to think about if it's < or =. You know immediately that you are iterating over all the list, However, sadly, people will forget about the i++ at the end :D So, I say Vim!

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

#7


1  

Lets not forget that some collections do not implement a direct access operator[] and that you have to iterate using the IEnumerable interface which is most easily accessed with foreach().

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