从foreach循环获取当前索引

这个问题在这里已经有了答案:

  • 你如何获得foreach循环的当前迭代的索引? 31个答案

  • IEnumerable list = DataGridDetail.ItemsSource as IEnumerable;
    List<string> lstFile = new List<string>();
    
    int i = 0;
    foreach (var row in list)
    {
    bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row)).IsChecked;
    if (IsChecked)
    {
      MessageBox.show(i);
    --Here i want to get the index or current row from the list                   
    
    }
     ++i;
    }
    

    你不能,因为IEnumerable根本没有索引...... 如果你确定你的枚举值小于int.MaxValue元素 (或者如果你使用long索引, long.MaxValue ),你可以:

  • 不要使用foreach,并使用for循环,首先将IEnumerable转换为泛型可枚举:

    var genericList = list.Cast<object>();
    for(int i = 0; i < genericList.Count(); ++i)
    {
       var row = genericList.ElementAt(i);
       /* .... */
    }
    
  • 有一个外部索引:

    int i = 0;
    foreach(var row in list)
    {
       /* .... */
       ++i;
    }
    
  • 通过Linq获取索引:

    foreach(var rowObject in list.Cast<object>().Select((r, i) => new {Row=r, Index=i}))
    {
      var row = rowObject.Row;
      var i = rowObject.Index;
      /* .... */    
    }
    
  • 在你的情况下,因为你的IEnumerable不是通用的,所以我宁愿使用带有外部索引的foreach (第二种方法)......否则,你可能想在你的循环外部使用Cast<object>将它转换为IEnumerable<object>

    你的数据类型不是从问题中清除,但我假设object因为它是一个项目源(它可以是DataGridRow )...你可能想要检查它是否可以直接转换为通用IEnumerable<object>而不必调用Cast<object>() ,但我不会做出这样的假设。


    所有这一切说:

    “索引”的概念对于IEnumerable是外来的。 IEnumerable可能是无限的。 在您的示例中,您使用的是DataGridItemsSource ,因此您的IEnumerable更可能仅仅是一个对象(或DataRows )的列表,其中有限的(并且希望少于int.MaxValue )成员数,但IEnumerable可以表示任何东西可以枚举(枚举可能永远不会结束)。

    以这个例子:

    public static IEnumerable InfiniteEnumerable()
    {
      var rnd = new Random();
      while(true)
      {
        yield return rnd.Next();
      }
    }
    

    所以如果你这样做:

    foreach(var row in InfiniteEnumerable())
    {
      /* ... */
    }
    

    你的foreach将会是无限的:如果你使用了一个int (或long )索引,你最终会溢出它(除非你使用unchecked上下文,否则它会抛出一个异常,如果你继续添加它:即使你使用unchecked ,这个指数也是毫无意义的......在某些时候 - 当它溢出时 - 对于两个不同的值,指数将是相同的)。

    所以,尽管给出的例子适用于典型的用法,但如果可以避免的话,我宁愿不使用索引。


    使用Enumerable.Select <TSource,TResult>方法(IEnumerable <TSource>,Func <TSource,Int32,TResult>)

    list = list.Cast<object>().Select( (v, i) => new {Value= v, Index = i});
    
    foreach(var row in list)
    {
        bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row.Value)).IsChecked;
        row.Index ...
    }
    
    链接地址: http://www.djcxy.com/p/52965.html

    上一篇: Get current index from foreach loop

    下一篇: foreach with index