Search code examples
c#visual-studioxnamonogame

List seems to still exist after finishing program


I have found a pretty strange thing while coding an Asteroid Destroyer minigame using MonoGame with Visual Studio 2017. In the LoadContent() method I load the textures for my spaceship in a list of Sprites which is created on the spot. Then this list is fed into the Spaceship constructor so that the spaceship gets its textures. The code is as follows:

protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            List<Sprite> spaceship1Sprites = new List<Sprite>
            {
                new Sprite(Content, "Spaceship1On"),
                new Sprite(Content, "Spaceship1Off"),
                new Sprite(Content, "Bullet1")
            };

            spaceship1 = new Spaceship(spaceship1Sprites, new Vector2(graphics.GraphicsDevice.DisplayMode.Width / 2, graphics.GraphicsDevice.DisplayMode.Height / 2))
            {
                Controls = new Input(Keys.W, Keys.D, Keys.A, Keys.Space)
            };
        }

The strange thing is that, if after running the program once, I delete the lines in which the Sprite list is defined,

            //List<Sprite> spaceship1Sprites = new List<Sprite>
            //{
            //    new Sprite(Content, "Spaceship1On"),
            //    new Sprite(Content, "Spaceship1Off"),
            //    new Sprite(Content, "Bullet1")
            //};

the program will still run, even though the list is not defined anywhere else in the program and the Spaceship constructor should be getting an unexistent list as its first parameter. How can this still work?

This is not something that is preventing me from making my program work, but I would still like to know what is the cause so that I know a little bit more about how C# works.

Edit: Adding the rest of the code in the Game1 class. The Spaceship class does not contain the list spaceship1Sprites, it has three fields for the three sprites, which are loaded in the constructor.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.IO;

namespace Asteroid_Destroyer
{
    public class Game1 : Game
    {
        public static GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        KeyboardState currentKeyboardState, previousKeyboardState;
        bool paused = false;

        Spaceship spaceship1;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            //Change screen resolution
            graphics.PreferredBackBufferWidth = graphics.GraphicsDevice.DisplayMode.Width;
            graphics.PreferredBackBufferHeight = graphics.GraphicsDevice.DisplayMode.Height;
            graphics.IsFullScreen = true;
            graphics.HardwareModeSwitch = false; //fullscreen borderless
            graphics.ApplyChanges();

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            List<Sprite> spaceship1Sprites = new List<Sprite>
            {
                new Sprite(Content, "Spaceship1On"),
                new Sprite(Content, "Spaceship1Off"),
                new Sprite(Content, "Bullet1")
            };

            spaceship1 = new Spaceship(spaceship1Sprites, new Vector2(graphics.GraphicsDevice.DisplayMode.Width / 2, graphics.GraphicsDevice.DisplayMode.Height / 2))
            {
                Controls = new Input(Keys.W, Keys.D, Keys.A, Keys.Space)
            };
        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            currentKeyboardState = Keyboard.GetState();

            if (currentKeyboardState.IsKeyDown(Keys.Escape))
                Exit();

            if(currentKeyboardState.IsKeyDown(Keys.P) && previousKeyboardState.IsKeyUp(Keys.P))
                paused = paused ? false : true;

            if (!paused)
                spaceship1.Update();

            base.Update(gameTime);
            previousKeyboardState = currentKeyboardState;
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            spriteBatch.Begin();
            spaceship1.Draw(spriteBatch);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}

Edit 2: Solved! As expected, it wasn't something about the code but about what Visual Studio was running. Somehow my Visual Studio configuration let the previous working version run if there is an error in the current build... But I have already found the setting to change this, so mystery solved!


Solution

  • Apparently there is an option in the settings which enables Visual Studio to run a previous working build of the project if there is an error, which was enabled by default in my installation (unless I had inadvertedly enabled the option by mistake).

    I found the solution thanks to this answer in another question while trying to investigate the issue:

    Try changing this value:

    • Tools
      • Options
        • Projects and Solutions
          • Build and Run
            • On Run, when build or deployment errors occur: Do not Launch