帮助将foreach循环转换为c#中的while循环

时间:2010-03-24 06:42:43

标签: c# foreach

我通过在这里阅读你的好答案来学习,从foreach循环中删除项目并不是一个好习惯,因为它(并且我引用)“锯掉你正坐在的分支上”。

我的代码目前会从下拉列表中删除文本,但实际项目仍然存在(仅显示文本)。

换句话说,它不是删除,也可能是因为你无法从foreach循环中删除。

经过几个小时的尝试后,我无法理解这种做法。

//For each checked box, run the delete code
for (int i = 0; i < this.organizeFav.CheckedItems.Count; i++)
{
    //this is the foreach loop
    foreach (ToolStripItem mItem in favoritesToolStripMenuItem.DropDownItems)
    {
        //This rules out seperators
        if (mItem is ToolStripMenuItem)
        {
            ToolStripMenuItem menuItem = mItem as ToolStripMenuItem;

            //This matches the dropdownitems text to the CheckedItems String
            if (((ToolStripMenuItem)mItem).Text.ToString() == organizeFav.CheckedItems[i].ToString())
            {
                //And deletes the item
                menuItem.DropDownItems.Remove(mItem);
            }
        }
    }
}

但它没有删除,因为它在foreach循环中! 我非常感谢您的帮助,如果有人能够了解这些代码,我会非常感激:)

亲切的问候

5 个答案:

答案 0 :(得分:5)

LINQ的乐趣!

// Loop through the checked items, same as you did.
foreach (var checkedItem in this.organizeFav.CheckedItems)
{
    // Cast from IEnumerable to IEnumerable<T> so we can abuse LINQ
    var matches = favoritesToolStripMenuItem.DropDownItems.Cast<ToolStripItem>()
                  // Only items that the Text match
                  .Where(item => item.Text == checkedItem.Text)
                  // Don't match separators
                  .Where(item => item is ToolStripMenuItem)
                  // Select the keys for the later .Remove call
                  .Select(item => item.Name);

    // Loop through all matches        
    foreach (var key in matches)
    {
        // Remove them with the Remove(string key) overload.
        favoritesToolStripMenuItem.Remove(key);
    }
}

答案 1 :(得分:3)

你不需要foreach循环 - 只需使用常规循环但反过来,从最后开始并开始。

//For each checked box, run the delete code
for (int i = 0; i < this.organizeFav.CheckedItems.Count; i++)
{
    //this *replaces* the foreach loop
    for(int j = favoritesToolStripMenuItem.DropDownItems.Count - 1; j >= 0; j--)
    {
        ToolStripMenuItem menuItem = favoritesToolStripMenuItem.DropDownItems[j] as ToolStripMenuItem; 

        //This rules out seperators
        if (menuItem != null)
        {
            //This matches the dropdownitems text to the CheckedItems String
            if (menuItem.Text.ToString() == organizeFav.CheckedItems[i].ToString())
            {
                favoritesToolStripMenuItem.DropDownItems.Remove(menuItem);
            }
        }
    }
 }

这是@ Kurresmack的代码重新排列,我只是在页面中直接编码,所以借口任何小的语法错误或任何明显我忽略的(免责声明:这是一个样本!)

您仍然可以将favoritesToolStripMenuItem.DropDownItems视为一个类似于您的集合,但您不必使用foreach对其进行枚举。这减少了几行代码,它起作用的原因是你以相反的顺序迭代它,你不会得到索引超出范围的异常。

答案 2 :(得分:0)

尝试这样的事情:

//For each checked box, run the delete code
for (int i = 0; i < this.organizeFav.CheckedItems.Count; i++)
        {
    List<ToolStripItem> toRemove = new List<ToolStripItem>();
//this is the foreach loop
            foreach (ToolStripItem mItem in favoritesToolStripMenuItem.DropDownItems)
            {

                //This rules out seperators
                if (mItem is ToolStripMenuItem)
                {
                    ToolStripMenuItem menuItem = mItem as ToolStripMenuItem;

             //This matches the dropdownitems text to the CheckedItems String
                    if (((ToolStripMenuItem)mItem).Text.ToString() == organizeFav.CheckedItems[i].ToString())
                    {
                        toRemove.Add(mItem);
                    }
                }
            }
        foreach(var item in toRemove)
        {
        favoritesToolStripMenuItem.DropDownItems.Remove(item);
        }
        }

答案 3 :(得分:0)

在我看来,使代码工作的方法是:
1.创建favoritesToolStripMenuItem.DropDownItems集合类型的实例 2.在foreach循环中,将您不想删除的所有项目添加到该集合中 3.使favoritesToolStripMenuItem.DropDownItems指向新集合。或清除favoritesToolStripMenuItem.DropDownItems并将新集合中的项目加载到其中。

希望这有帮助

答案 4 :(得分:0)

而不是foreach使用反向for - 循环:

for(int reverseIndex = myList.Count - 1; reverseIndex >= 0; reverseIndex--)
{
    var currentItem = myList[reverseIndex];
    if(MatchMyCondition(currentItem))
    {
        myList.Remove(currentItem);
    }
}