Getter C#上的StackOverflowException

Luu*_*ter 4 c# uwp

get;在抽象类的属性上得到StackOverflowException .

public abstract class SenseHatSnake
    {

        private readonly ManualResetEventSlim _waitEvent = new ManualResetEventSlim(false);

        protected SenseHatSnake(ISenseHat senseHat)
        {
            SenseHat = senseHat;
        }

        protected static ISenseHat SenseHat { get; set; } // This Line

        public virtual void Run()
        {
            throw new NotImplementedException();
        }

        protected void Sleep(TimeSpan duration)
        {
            _waitEvent.Wait(duration);
        }

    }
Run Code Online (Sandbox Code Playgroud)

我正在设置并在此处获取:

public class SnakeGame : SenseHatSnake
{
    private readonly int _gameSpeed = 1000;
    private static Timer _updatePositionTimer;
    private bool _gameOver = false;

    public readonly Movement Movement = new Movement(SenseHat);
    public readonly Food Food = new Food(SenseHat);
    public readonly Body Body = new Body(SenseHat);
    public readonly Display Display = new Display(SenseHat);
    public readonly Draw Draw = new Draw(SenseHat);

    public SnakeGame(ISenseHat senseHat)
        : base(senseHat)
    {
    }
    //More code
}
Run Code Online (Sandbox Code Playgroud)

其中一个类看起来像这样:

public class Movement : SnakeGame
{

    public Movement(ISenseHat senseHat)
        : base(senseHat)
    {
    }
    //More code
}
Run Code Online (Sandbox Code Playgroud)

据我所知,StackOverflowException意味着我在某个地方有一个无限循环或无限递归,但老实说我不知道​​在哪里,也不知道如何解决它.

Bag*_*ich 13

这一行SnakeGame会导致递归

public readonly Movement Movement = new Movement(SenseHat);
Run Code Online (Sandbox Code Playgroud)

由于Movement继承自SnakeGame,它的构造函数将初始化SnakeGame,再次调用上面的行来初始化它自己的Movement字段.这会导致递归.


Eri*_*ert 5

溢出的起源已经在其他答案中得到确认,其他答案已经指出了程序草图中的建筑设计问题.

我想我会简要说一下如何自己调试这些问题.

第一:当遇到堆栈溢出时,几乎总是存在无限递归.当一个明显没有堆栈溢出的成员报告溢出时,发生了什么?这发生了:

void Bad()
{
    Good();
    Bad();
}
Run Code Online (Sandbox Code Playgroud)

如果Bad被调用那么它将堆栈溢出,但大多数时候会报告溢出Good,因为Good可能使用比任何单个调用更多的堆栈Bad.

你需要做的是查看调用堆栈,因为它会Good / Bad / Bad / Bad / Bad ... 告诉你它Bad正在进行无限递归. 找到递归源的关键是直接或间接地找到实际调用自身的东西.使用您可以使用的仪器; 异常包含调用堆栈的跟踪.