我应该声明并创建一个 class 内部循环的实例吗?

Should I declare and create an instance of a class inside loop?

我写了一个简单的控制台游戏(具体来说是 TicTacToe)来练习。游戏结束后,我需要重置游戏,因此我正在创建游戏的新实例 class。

class 的旧实例是否在创建新实例之前被销毁?

如果不是,那么它会堆积在内存中,这不好。那么这里更好的做法是什么?

        static void Main(string[] args)
        {
            bool restart = true;  //stores decision whether to restart the game
            do
            {
                Game game = new Game();  //a simple console game
                game.start();            //start -> play -> game over
                restart = playAgain();   //playAgain returns a boolean
            } while (restart);
        }

如果相关,代码是用 c# 编写的。

据我所知(因为我对此比较陌生)您在 do 范围内声明的所有变量都是本地的,当程序超出该范围时,这些变量将被销毁。因此,您在 do 范围内声明的游戏实例 class 是本地的,因此当 while 循环再次检查条件时将被销毁。

当您创建名为 game 的游戏 class 的新实例时,您所做的只是将变量 game 设置为一个新实例。 game 保存在内存中,因此下次您开始游戏时,它将使用变量 game,并且无论它处于什么状态,都会将其设置为一个新实例。这意味着 class 的实例永远不会超过一次,无论它是否在 do/while 循环中,因为您使用的是相同的变量。

简短版本:

Should I declare and create an instance of a class inside loop?

是的,如果您只需要循环内的那个实例。


当我们创建对象时

Game game = new Game();

...只要有对它的引用,它就“存在”在内存中。当不再有任何对象引用时,它就可用于垃圾回收。

所以问题是,创建的 Game 对象有哪些引用?似乎只有一个引用,即您分配给它的 game 变量。

所以现在的问题是,这个变量能活多久?它在定义它的范围内存在。在这种情况下,您在 do 循环中定义它。一旦循环的执行结束(几行之后),变量就会超出范围。换句话说,定义它的范围不再存在。简单来说,该变量不再存在。

该变量是对该 Game 对象的唯一引用。当变量超出范围时,不再有对该 Game 对象的任何引用。它将被垃圾收集。 (这不会立即发生,但我们不必担心它发生的确切时间。我们通常不关心。这是框架为我们担心的事情。)

如果循环重复怎么办?将该循环的内部视为一种被反复调用的方法。当它再次被调用时,game 变量是新的,因为它是在循环内声明的。它不“知道”关于循环的先前执行或先前的 Game 对象的任何信息。该变量在循环迭代结束时超出范围。

我们如何判断变量的范围是什么?一种简单的方法是查看允许我们在哪里使用它。

如果您尝试编写此代码,请在循环外使用 game 变量:

        static void Main(string[] args)
        {
            bool restart = true;  //stores decision whether to restart the game
            do
            {
                Game game = new Game();  //a simple console game
                game.start();            //start -> play -> game over
                restart = playAgain();   //playAgain returns a boolean
            } while (restart);

        }
        game.Start(); // <-- Outside the loop where it was declared

...它不会编译。那是因为变量是在循环内声明的,所以它在循环外是不可用的。就像我们在一个方法中声明一个局部变量一样,它在另一个方法中不可见或不可访问。