在c#中是否有一些我没有遇到过的罕见的语言构造(比如我最近学过的一些,一些在Stack Overflow上)来获得表示foreach循环的当前迭代的值?

例如,我目前根据具体情况做这样的事情:

int i = 0;
foreach (Object o in collection)
{
    // ...
    i++;
}

当前回答

我只是遇到了这个问题,但在我的情况下思考这个问题给出了最好的解决方案,与预期的解决方案无关。

It could be quite a common case, basically, I'm reading from one source list and creating objects based on them in a destination list, however, I have to check whether the source items are valid first and want to return the row of any error. At first-glance, I want to get the index into the enumerator of the object at the Current property, however, as I am copying these elements, I implicitly know the current index anyway from the current destination. Obviously it depends on your destination object, but for me it was a List, and most likely it will implement ICollection.

i.e.

var destinationList = new List<someObject>();
foreach (var item in itemList)
{
  var stringArray = item.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);

  if (stringArray.Length != 2)
  {
    //use the destinationList Count property to give us the index into the stringArray list
    throw new Exception("Item at row " + (destinationList.Count + 1) + " has a problem.");
  }
  else
  {
    destinationList.Add(new someObject() { Prop1 = stringArray[0], Prop2 = stringArray[1]});
  }
}

我认为,虽然不总是适用,但常常足以值得一提。

不管怎样,关键是有时在你的逻辑中已经有了一个不明显的解决方案……

其他回答

像这样的怎么样?注意,如果myEnumerable为空,myDelimitedString可能为空。

IEnumerator enumerator = myEnumerable.GetEnumerator();
string myDelimitedString;
string current = null;

if( enumerator.MoveNext() )
    current = (string)enumerator.Current;

while( null != current)
{
    current = (string)enumerator.Current; }

    myDelimitedString += current;

    if( enumerator.MoveNext() )
        myDelimitedString += DELIMITER;
    else
        break;
}

为什么?!

如果你使用List,最简单的方法是使用for而不是foreach:

for (int i = 0 ; i < myList.Count ; i++)
{
    // Do something...
}

或者如果你想使用foreach:

foreach (string m in myList)
{
     // Do something...
}

你可以用它来知道每个循环的索引:

myList.indexOf(m)

使用@FlySwat的答案,我想出了这个解决方案:

//var list = new List<int> { 1, 2, 3, 4, 5, 6 }; // Your sample collection

var listEnumerator = list.GetEnumerator(); // Get enumerator

for (var i = 0; listEnumerator.MoveNext() == true; i++)
{
  int currentItem = listEnumerator.Current; // Get current item.
  //Console.WriteLine("At index {0}, item is {1}", i, currentItem); // Do as you wish with i and  currentItem
}

你使用GetEnumerator来获取枚举器,然后使用for循环来进行循环。然而,诀窍是使循环的条件listEnumerator.MoveNext() == true。

由于枚举器的MoveNext方法如果存在下一个元素并且可以访问它,则返回true,因此循环条件使循环在耗尽要遍历的元素时停止。

可以这样做:

public static class ForEachExtensions
{
    public static void ForEachWithIndex<T>(this IEnumerable<T> enumerable, Action<T, int> handler)
    {
        int idx = 0;
        foreach (T item in enumerable)
            handler(item, idx++);
    }
}

public class Example
{
    public static void Main()
    {
        string[] values = new[] { "foo", "bar", "baz" };

        values.ForEachWithIndex((item, idx) => Console.WriteLine("{0}: {1}", idx, item));
    }
}
// using foreach loop how to get index number:
    
foreach (var result in results.Select((value, index) => new { index, value }))
{
    // do something
}