我在使用带有WinForm ListView控件的foreach语句时遇到了困难。以下两个代码块演示了我正在尝试做的事情。它适用于for循环,但不适用于foreach。
foreach(var item in listView.Items){
item. <-Can't access any of the subitems of this item
}
VS
for(int i=0;i<listView.Items.Count;i++){
listView.Items[i].Subitems[1] <- Here I can access the sub items
}
我正在尝试使用foreach循环,以便我可以更轻松地从ListView中删除项目。
答案 0 :(得分:49)
您需要指定类型:
foreach(ListViewItem item in listView.Items){
回答你的意见:
这是因为大多数控件的项集都实现了非通用ICollection
(以及IEnumerable
),例如ListViewItemCollection
请参阅this MSDN entry。由于它没有实现泛型ICollection<T>
或IEnumerable<T>
,因此编译器无法通过查看集合本身来猜测项的类型,因此您必须告诉它它们是类型的ListViewItem
而非使用var
。
答案 1 :(得分:4)
如果集合中的项目明确指定,则需要指定类型。 var
关键字使用类型推断来确定变量的类型。对于var
子句中的foreach
,它使用IEnumerable
的特定实现来确定类型。
IEnumerable
(而非通用IEnumerable<T>
),那么var
将为object
IEnumerable<T>
(例如,IEnumerable<int>
),则var
将为T
(在此示例中,var
将是int
)在您的情况下,ListViewItemCollection
未实现IEnumerable<T>
的任何通用形式,因此var
被假定为object
。但是,如果枚举只实现IEnumerable
,编译器将允许您为迭代器变量指定更具体的类型,并且它会自动将强制转换插入到该特定类型。
请注意,因为有一个转换操作符,如果该对象不属于该特定类型,则转换将在运行时失败。例如,我可以这样做:
List<object> foo = new List<object>();
foo.Add("bar");
foo.Add(1);
foreach(string bar in foo)
{
}
这是合法的,但是当迭代器到达第二个项目时会失败,因为它不是string
。
答案 2 :(得分:2)
您需要拥有该项目的类型 - 在这种情况下:ListViewItem
。
此外,如果您计划从集合中删除项目并使用foreach循环,则无法直接从循环中删除 - 您需要将每个项目添加到新集合中并删除在循环结束后从原件中删除该集合中的所有项目。
答案 3 :(得分:0)
使用漂亮的LINQ收藏品
using System.Linq;
foreach(var item in listView.Items.Cast<ListViewItem>()){
item.BackColor = ...
}