c#栈没有更新
本文关键字:更新 | 更新日期: 2023-09-27 18:14:17
由于某种原因,我修改的代码似乎不能正常运行。调试时没有异常错误,但是它的功能与原始代码(列表)不一样-也就是说它似乎没有更新。我把它定位到我认为导致问题的代码区域:
我的原始代码(使用List)的工作:
private List<Gem> gems = new List<Gem>();
private List<Enemy> enemies = new List<Enemy>();
private void UpdateGems(GameTime gameTime)
{
for (int i = 0; i < gems.Count; ++i)
{
Gem gem = gems[i];
gem.Update(gameTime);
if (gem.BoundingCircle.Intersects(Player.BoundingRectangle))
{
gems.RemoveAt(i--);
OnGemCollected(gem, Player);
}
}
}
这是我修改后的代码,将List替换为Stack,这不能正常工作:
private Stack<Gem> gems = new Stack<Gem>();
private Stack<Enemy> enemies = new Stack<Enemy>();
private void UpdateGems(GameTime gameTime)
{
for (int i = 0; i < gems.Count; ++i)
{
Gem gem = gems.Peek();
gem.Update(gameTime);
if (gem.BoundingCircle.Equals(Player.BoundingRectangle))
{
gems.Pop();
OnGemCollected(gem, Player);
}
}
}
任何想法?
我不知道你到底需要什么,但是循环看起来有点奇怪:如果你在第一个回合不从堆栈中pop()
任何东西,peek()
将始终返回相同的元素。堆栈数据结构不被索引,它只允许弹出/窥视最后推入的元素。使用列表的代码的行为当然不同,因为您实际上是在检查列表中的所有元素。
根据定义,当您从堆栈中弹出某项时,您将删除最后添加的项。因此,您已经颠倒了从集合中检查和删除Gem
对象的顺序-当您在Stack<Gem>
版本中检查Peek
和Pop
和BoundingCircle.Equals()
时,您不会像在List<Gem>
版本中那样检查集合中的第一个项目。
List可以在任何方向上迭代,只需以适当的方式调整索引器。栈是后进先出(后进先出),所以你只能访问最后添加的项。
我认为当调用peak方法时,它可能会在堆栈集合的顶部保留对该项目的引用。当你调用到弹出方法。它不能正常工作
我复制了您的示例并将其放入如下的控制台应用程序
class Program
{
private static Stack<Gem> gems = new Stack<Gem>();
private Stack<Enemy> enemies = new Stack<Enemy>();
static void Main(string[] args)
{
gems.Push(new Gem
{
BoundingCircle = new BoundingCircle
{
Name = "abc"
}
});
gems.Push(new Gem
{
BoundingCircle = new BoundingCircle
{
Name = "def"
}
});
UpdateGems(new GameTime());
}
private static void UpdateGems(GameTime gameTime)
{
for (int i = 0; i < gems.Count; ++i)
{
Gem gem = gems.Peek();
gem.Update(gameTime);
if (gem.BoundingCircle.Equals(Player.BoundingRectangle))
{
gems.Pop();
OnGemCollected(gem, null);
}
}
}
private static void OnGemCollected(Gem gem, Player player)
{
}
}
public class Gem
{
public void Update(GameTime gameTime)
{
}
public BoundingCircle BoundingCircle { get; set; }
}
public class Enemy
{
}
public class GameTime
{
}
public class BoundingCircle : Bounding
{
public override bool Equals(object obj)
{
var temp = (Bounding) obj;
return Name.Equals(temp.Name, StringComparison.InvariantCulture);
}
}
public class Player
{
static Player()
{
BoundingRectangle = new BoundingRectangle
{
Name = "def"
};
}
public static BoundingRectangle BoundingRectangle { get; set; }
}
public class BoundingRectangle : Bounding
{
}
public abstract class Bounding
{
public string Name { get; set; }
}
工作得很好。请注意,你的Equals函数必须被BoundingCircle类覆盖。