从 foreach 循环获取当前索引
Get current index from foreach 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
}
}
如何实现
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;
}
这里有两个选择,1. 使用 for
代替 foreach
对于 iteration.But 在你的情况下集合是 IEnumerable 并且集合的上限未知所以 foreach将是最好的选择。所以我更喜欢使用另一个整数变量来保存迭代计数:这里是代码:
int i = 0; // for index
foreach (var row in list)
{
bool IsChecked;// assign value to this variable
if (IsChecked)
{
// use i value here
}
i++; // will increment i in each iteration
}
你不能,因为 IEnumerable
根本没有索引... 如果你确定你的枚举数少于 int.MaxValue
个元素 (或 long.MaxValue
如果你使用 long
索引),你可以:
不要使用 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
)...你可能想检查它是否直接无需调用 Cast<object>()
即可转换为通用 IEnumerable<object>
,但我不会做出此类假设。
这就是说:
"index" 的概念对于 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())
{
/* ... */
}
你的 foreach
将是无限的:如果你使用 int
(或 long
)索引,你最终会溢出它(除非你使用 unchecked
上下文,如果你继续添加它会抛出一个异常:即使你使用 unchecked
,索引也将毫无意义......在某些时候 - 当它溢出时 - 索引将是相同的两个不同的值)。
因此,虽然给出的示例适用于典型用法,但如果可以避免的话,我宁愿根本不使用索引。
使用Enumerable.Select<TSource, TResult> Method (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 ...
}
使用 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
}
}
如何实现
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;
}
这里有两个选择,1. 使用 for
代替 foreach
对于 iteration.But 在你的情况下集合是 IEnumerable 并且集合的上限未知所以 foreach将是最好的选择。所以我更喜欢使用另一个整数变量来保存迭代计数:这里是代码:
int i = 0; // for index
foreach (var row in list)
{
bool IsChecked;// assign value to this variable
if (IsChecked)
{
// use i value here
}
i++; // will increment i in each iteration
}
你不能,因为 IEnumerable
根本没有索引... 如果你确定你的枚举数少于 int.MaxValue
个元素 (或 long.MaxValue
如果你使用 long
索引),你可以:
不要使用 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
)...你可能想检查它是否直接无需调用 Cast<object>()
即可转换为通用 IEnumerable<object>
,但我不会做出此类假设。
这就是说:
"index" 的概念对于 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())
{
/* ... */
}
你的 foreach
将是无限的:如果你使用 int
(或 long
)索引,你最终会溢出它(除非你使用 unchecked
上下文,如果你继续添加它会抛出一个异常:即使你使用 unchecked
,索引也将毫无意义......在某些时候 - 当它溢出时 - 索引将是相同的两个不同的值)。
因此,虽然给出的示例适用于典型用法,但如果可以避免的话,我宁愿根本不使用索引。
使用Enumerable.Select<TSource, TResult> Method (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 ...
}