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);
            }
        }
    }

任何想法?

c#栈没有更新

我不知道你到底需要什么,但是循环看起来有点奇怪:如果你在第一个回合不从堆栈中pop()任何东西,peek()将始终返回相同的元素。堆栈数据结构不被索引,它只允许弹出/窥视最后推入的元素。使用列表的代码的行为当然不同,因为您实际上是在检查列表中的所有元素。

根据定义,当您从堆栈中弹出某项时,您将删除最后添加的项。因此,您已经颠倒了从集合中检查和删除Gem对象的顺序-当您在Stack<Gem>版本中检查PeekPopBoundingCircle.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类覆盖。