由于 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>
。
根据问题中没有明确说明数据类型,但我认为它是一个项源(可能是 DataGridRow
),你可以检查是否可以直接将其转换为泛型的 IEnumerable<object>
而不需要调用 Cast<object>()
,但我不会做出这样的假设。
总之:
“索引”的概念对于 IEnumerable
来说是陌生的。一个 IEnumerable
可能是无限的。在您的示例中,您正在使用 DataGrid
的 ItemsSource
,因此您的 IEnumerable
更可能只是一组对象(或 DataRows
),具有有限的(并且希望小于 int.MaxValue
)成员数量,但 IEnumerable
可以表示任何可枚举的东西(而枚举可能永远不会结束)。
以下是一个例子:
public static IEnumerable InfiniteEnumerable()
{
var rnd = new Random();
while(true)
{
yield return rnd.Next();
}
}
如果你这样做:
foreach(var row in InfiniteEnumerable())
{
/* ... */
}
如果您使用 int
(或 long
)索引,您的foreach
循环将是无限的:最终会溢出(除非您使用了一个 unchecked
上下文,否则如果您不断添加,它会抛出异常:即使您使用了 unchecked
,索引也会变得毫无意义...在某个时候 - 溢出时 - 索引将对于两个不同的值相同)。
因此,虽然给出的示例对于典型用法有效,但如果可能的话,我宁愿根本不使用索引。