从foreach循环获取当前索引

Gop*_*pal 9 c# silverlight foreach for-loop

使用C#和Silverlight

如何获取列表中当前项的索引?

码:

IEnumerable list = DataGridDetail.ItemsSource as IEnumerable;
List<string> lstFile = new List<string>();


foreach (var row in list)
{
  bool IsChecked = (bool)((CheckBox)DataGridDetail.Columns[0].GetCellContent(row)).IsChecked;
  if (IsChecked)
  {

    // Here I want to get the index or current row from the list                   

  }
}
Run Code Online (Sandbox Code Playgroud)

如何实现这一目标

Jcl*_*Jcl 21

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

  1. 不要使用foreach,并使用for循环,首先将您转换IEnumerable为通用枚举:

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

    int i = 0;
    foreach(var row in list)
    {
       /* .... */
       ++i;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 通过Linq获取索引:

    foreach(var rowObject in list.Cast<object>().Select((r, i) => new {Row=r, Index=i}))
    {
      var row = rowObject.Row;
      var i = rowObject.Index;
      /* .... */    
    }
    
    Run Code Online (Sandbox Code Playgroud)

在你的情况下,因为你IEnumerable不是通用的,我宁愿使用foreachwith外部索引(第二种方法)...否则,你可能想让Cast<object>你的循环外部将其转换为IEnumerable<object>.

您的数据类型在问题上并不清楚,但我假设object因为它是一个项目源(可能是DataGridRow)...您可能想要检查它是否可以直接转换为通用IEnumerable<object>而无需调用Cast<object>(),但我会做出否定这样的假设.


这一切都说:

"索引"的概念对于一个人来说是陌生的IEnumerable.一个IEnumerable可能是无限的.在您的示例中,您使用的ItemsSource是a DataGrid,因此您更可能IEnumerable只是一个对象列表(或DataRows),具有有限(并且希望少于int.MaxValue)数量的成员,但IEnumerable可以表示可以枚举的任何内容(以及枚举)可能永远不会结束).

举个例子:

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

所以,如果你这样做:

foreach(var row in InfiniteEnumerable())
{
  /* ... */
}
Run Code Online (Sandbox Code Playgroud)

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

因此,虽然给出的示例适用于典型用法,但如果可以避免使用,我宁愿不使用索引.


tap*_*osh 6

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你能使用`for` ...:P,我没有看到使用`foreach`的意义 (3认同)