如何在foreach循环中编辑迭代器

本文关键字:编辑 迭代器 循环 foreach | 更新日期: 2023-09-27 17:49:45

场景

我有一个举办比赛的系统,每个比赛都有一个独特的成员名单。(该列表是list<T>(

我希望用户能够从该种族的成员列表中删除一个成员(如果他们是该成员(。

问题

我正在尝试让以下代码工作:

foreach (string item in hillracing.searchRaces(RaceID).RaceList) // Loop through List with foreach.
{
    if (item == SelectedItem)
    {
        item = null;
    }
}

我无法编辑变量,因为它在foreach循环中,我如何用另一种方式实现这一点?

如何在foreach循环中编辑迭代器

您只需存储它,然后从集合中删除它。

var toRemove = null;
foreach (string item in hillracing.searchRaces(RaceID).RaceList) // Loop through List with foreach.
{
    if (item == SelectedItem)
    {
        toRemove = item;
        break; //Can break here if you're sure there's only one SelectedItem
    }
}
hillracing.searchRaces(RaceID).Racelist.Remove(toRemove);

不过在这种情况下,您也可以只使用hillracing.searchRaces(RaceID).Racelist.Remove(SelectedItem);,并且根本不会使用foreach循环。

您不能修改使用foreach循环的集合。foreach中使用的集合是不可变的。这是经过设计的。

foreach语句用于遍历集合以获得您想要但不能用于添加或删除的信息源集合中的项,以避免不可预测的副作用。如果需要添加或删除源集合中的项,请使用for循环。

使用Linq,您不需要循环来查找要作废的条目。。。

// Use of Single() here assumes the object definitely exists. 
// Use SingleOrDefaul() if there is a chance it might not exist.
var item = hillracing.searchRaces(RaceID)
                     .RaceList
                     .Where(x => x.Item == SelectedItem).Single();  
item = null;

编辑:由于您已经更改了从列表中删除项目的要求,我认为您只需要使用找到的项目调用Remove方法。所以代码变成

// Use of Single() here assumes the object definitely exists. 
// Use SingleOrDefaul() if there is a chance it might not exist.
var item = hillracing.searchRaces(RaceID)
                     .RaceList
                     .Where(x => x.Item == SelectedItem).Single();  
hillracing.searchRaces(RaceID).RaceList.Remove(item);

foreach循环中不能这样做。如果是允许随机访问的IList/IList<T>,如数组或列表,则可以使用for-循环:

List<string> = hillracing.searchRaces(RaceID).RaceList;
for(int i = 0; i < list.Count; i++)
{
    if(list[i] == SelectedItem)
         list[i] = null;
}

因此,您不能在foreach中添加或删除项,但也不能替换引用。对象引用原始值,因此您可以修改对象(如果字符串不是不可变的(,但不能在foreach中替换引用本身。这是相关的。

使用现有的Remove()-方法为您搜索并删除项目:

hillracing.searchRaces(RaceID).RaceList.Remove(SelectedItem);