从List<>中删除对象条件

时间:2014-04-14 12:55:27

标签: c# xna

我正在创建一个蚂蚁模拟程序,在这里蚂蚁四处旅行并收集食物并将其带到巢中。当从食物中收集到一定数量的蚂蚁时,我希望食物源消失。我有一个单独的类,用于antObject,foodObject和nestObject。

我的fixedFood类中有一个'int foodleft = 25'变量。当用户点击时,食物对象被放置在屏幕上,并立即被添加到列表对象'foodList'中。 draw方法绘制列表中的所有对象。当'foodLeft'变量达到0时,我无法弄清楚如何使特定的食物对象消失!

这是我在fixedFood类中的draw方法 -

  public void Draw(SpriteBatch spriteBatch, List<stationaryFood> foodlist)
    {
        foreach (stationaryFood food in foodlist)
        {
            spriteBatch.Draw(foodImage, foodBoundingRectangle, foodColor);                                                              //draw each food object in foodList
        }
    }

这是我在更新方法

中主要'game1'类中尝试解决问题的方法
  if (foodList.Count > 0)
        {
            foreach (stationaryFood f in foodList)
            {
                if (f.FoodLeft == 0)
                {
                    foodList.Remove(f);


                }
            }
        }

然而这不起作用!我得到一个'未处理的无效操作错误'。

在我的主游戏类1中的绘制方法中,我有这个

        foreach (stationaryFood f in foodList)
        {
            f.Draw(spriteBatch, foodList);
        }

有人可以看到我哪里出错吗?

3 个答案:

答案 0 :(得分:3)

您正在迭代它时修改集合,因此您获得异常的原因。在你的情况下,而不是:

foreach (stationaryFood f in foodList)
{
    if (f.FoodLeft == 0)
    {
        foodList.Remove(f);
    }
}

改为执行此操作(假设它在XNA中可用):

foodList.RemoveAll(x => x.FoodLeft == 0)

如果不是,您可以在this问题中查看答案。

答案 1 :(得分:0)

George Howarth的答案将完美无缺。

如果您对lambda表达式感到不舒服,可以尝试反向迭代

foreach (stationaryFood f in foodList.Reverse<stationaryFood>())
{
    if (f.FoodLeft == 0)
    {
        foodList.Remove(f);
    }
}

反向迭代允许我们循环访问集合并同时删除项目。

答案 2 :(得分:0)

序言:

游戏编程是开始使用C#的好方法,但我建议您仔细阅读forforeach等基本结构以及语言约定。

Microsoft Virtual Academcy Programming in C# Jump Start中的前五个模块将大大增加您对该语言的理解。

答案:

我看不出在foodlist课程中使用stationaryFood的原因。这将绘制重叠的纹理,这是毫无意义的。

public void Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Draw(foodImage, foodBoundingRectangle, foodColor);
}

您可以创建一个从列表中删除项目的方法。

private void RemoveFood(List<stationaryFood> foodlist)
{
    var foodToRemove = new List<stationaryFood>();

    foreach(var f in foodlist)
    {
        if(f.FoodLeft == 0)
        {
            foodToRemove.Add(f);
        }
    }

    foreach(var f in foodToRemove)
    {
        foodlist.Remove(f);
    }
}

稍后当你了解lambdas时,它可以简化为:

private void RemoveFood(List<stationaryFood> foodlist)
{
    foodlist.RemoveAll(food => food.FoodList == 0);
}

您可以在Update方法中添加此内容。

if (foodList.Count > 0)
{
    RemoveFood(fooList);
}

并更改Draw方法中的逻辑。

if (foodlist.Count > 0)
{
    foreach(var f in foodlist)
    {
        f.Draw(spriteBatch);
    }
}