Search code examples
c#stack-overflowgetter-setter

StackOverflowException in Variable SET function


I'm working on a Game Engine Library in C# from the ground up. I started by making a class "Window" which is an implementation of System.Window.Form to be as the main window for the game/games to be made with this engine.

After creating the code, i decided to make a test application to see if the Window class works. However, i keep getting a StackOverflowException on a setter for an item in the Window class. Please excuse the bad formatting. I could not get it to separate into 3 code locks for whatever reason. I know that the StackOverflowException means that the setter ran out of stack to put data on, but i'm not sure why. Can anyone provide advice please. Thanks. here is the code

Window.cs

namespace SharpGraphics
{
    internal class sgWindowParamiterModifiers
    {
        public bool sgWindowVisible { get => sgWindowVisible; set => sgWindowVisible = value; }
        public bool sgWindowAlwaysOnTopLayer { get => sgWindowAlwaysOnTopLayer; set => sgWindowAlwaysOnTopLayer = value; }
        public bool sgWindowIsBorderless { get => sgWindowIsBorderless; set => sgWindowIsBorderless = value; }

        public sgWindowParamiterModifiers()
        {
            sgWindowVisible = false;
            sgWindowAlwaysOnTopLayer = false;
            sgWindowIsBorderless = false;
        }

    }
    public class Window : Form
    {
        internal static String sgWindowTitle { get => sgWindowTitle; set => sgWindowTitle = value; }
        internal static typedefs.coords SgWindowCoords { get; set; }

        internal sgWindowParamiterModifiers sgWindowParamiters { get => sgWindowParamiters; set => sgWindowParamiters = value; }

        internal Color sgWindowColor { get => sgWindowColor; set => sgWindowColor = value; }

        internal Window(string windowTitle, typedefs.coords coords, sgWindowParamiterModifiers windowParamiters,
            Color windowColor)
        {
            sgWindowTitle = windowTitle;
            SgWindowCoords = coords;
            sgWindowParamiters = windowParamiters;
            sgWindowColor = windowColor;
        }

        public static bool sgCreateWindow(Window window)
        {
            bool sgWindowCreateSuccess = false;

            window.Visible = window.sgWindowParamiters.sgWindowVisible;
            
            //This is temporary. will add function to use alternative border layouts later
            //
            window.FormBorderStyle = (window.sgWindowParamiters.sgWindowIsBorderless ? FormBorderStyle.None : FormBorderStyle.Fixed3D);

            window.TopMost = window.sgWindowParamiters.sgWindowAlwaysOnTopLayer;

            try
            {
                window.Show();
            }
            catch(Exception Ex)
            {
                MessageBox.Show("The window failed to generate during function: SharpGraphics.Window.sgGenerateWindow()"
                    + Environment.NewLine + "The following is the internal error information:" + Environment.NewLine +
                    Ex.Message + Environment.NewLine + Ex.StackTrace, "Fatal Error 0xC0000002 - SG_WINDOW_FAILED_GENERATION_EXCEPTION",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(Ex.HResult);
            }

            sgWindowCreateSuccess = true;

            return sgWindowCreateSuccess;
        }
    }
}
'''


----------


//"coords" class from typedefs.cs
'''
  public class coords
        {
            public int X { get => X; set => X = value; } \\ <--- StackOverflow on X.set

            public int Y { get => Y; set => Y = value; }

            public coords(int x, int y)
            {
                X = x;
                Y = y;
            }
        }
'''


----------

//unit test from /test/testWindow.cs
'''
namespace SharpGraphics.test
{
    class windowTest
    {

        public static void Main(String[] args)
        {
            Window window = new Window("SharpGraphics Test Window", new typedefs.coords(1024, 768),
                new sgWindowParamiterModifiers(), Color.White);

            window.sgWindowParamiters.sgWindowVisible = true;

            Window.sgCreateWindow(window);

            return;

        }
    }
}
'''

Solution

  • You should not use properties getters/setters inside their own getters or setters respectively, that is what basically causes the stackoverflow. In this code:

    public int X { get => X; set => X = value; } \\ <--- StackOverflow on X.set 
    

    When you try to set X property internally it will recursively call it's own setter, which in turn will call it again ... and so on until you run out of stack space.

    One way to fix it - just change all this definitions to just ordinary auto-implemented properties:

    public int X { get; set; }