Переполнение стека из-за статического конструктора

128
30 марта 2021, 07:50

У меня есть Timer, который по определенным причинам я проинициализировал в статическом конструкторе. После того как я добавил этот статический конструктор, при создании экземпляров других классов в обычном конструкторе выдает Stack overflow exception. Почему это происходит.

class TimerData : INotifyPropertyChanged
{
    static TimerData()
    {           
        timer = new Timer(1000);
    }
    public TimerData()
    {
        // Stack overflow exception
        timer.Elapsed += TimerTick;
        timer.AutoReset = true;
        timer.Enabled = true;
        EventSecondsNotify += UpdateTime;
        // Ошибка возникает после добавления этой строки
        parameters = new Parameters();
    }
    private static Timer timer;
    private Parameters parameters;
}

Edit 1 Причина Stack overflow exception

class A
{
    public A()
    {
        b = new B();
    }
    B b;
}
class B
{
    public B()
    {
        a = new A();
    }
    A a;
}

Edit 2 как вызвать конструктор с параметрами?

public class TimerData : INotifyPropertyChanged
{
    public TimerData()
    {
        //parameters = new Parameters();
    }
    public TimerData(Parameters pr = null)
    {
        parameters = pr ?? new Parameters(this);
    }
    // Создаю экземпляр класса TimerData, чтобы через него вызвать
    // конструктор с параметрами. Выдает ошибку, что инициализатор
    // поля не может обращаться к нестатическому полю
    TimerData timerData = new TimerData();
    private Parameters parameters = new Parameters(timerData);
}

public class Parameters : INotifyPropertyChanged
{
    public Parameters()
    {
        //timerData = new TimerData();
        //timerData.EventSecondsNotify += DecreaseFatigue;
        //timerData.EventSecondsNotify += DecreaseSatiety;
    }
    // Как вызвать этот конструктор?
    public Parameters(TimerData td = null)
    {
        timerData = td ?? new TimerData(this);
        timerData.EventSecondsNotify += DecreaseFatigue;
        timerData.EventSecondsNotify += DecreaseSatiety;
    }
    private TimerData timerData;

}

Answer 1

У вас получается бесконечное создание экземпляров классов A and B.

Пояснение:

Когда вызывается конструктор класса A, создается объект класса B, у класса B, создается класс A, и так далее по кругу до бесконечности. Поэтому происходит переполнение.

Избавлением от этого может стать, передача ссылки классу B, на класс A, или наоборот.

public class A
{
    B b;
    public A(B classB = null)
    {
        b = classB ?? new B(this);
    }
}
public class B
{
    A a;
    public B(A classA = null)
    {
        a = classA ?? new A(this);
    }
}
READ ALSO
Xpath. Как добавить песню в vk.com?

Xpath. Как добавить песню в vk.com?

Пытаюсь c помощью XPath добавить песню в мои аудиозаписиПроблема в том, что кнопка добавления трека появляется только при наведении мышкой...

103
Выделение текста в TextBlock

Выделение текста в TextBlock

У меня есть кастомный TextBlock, который определяет ссылки в тексте и делает их кликабельнымиВозникла необходимость добавить возможность выделения...

124
Возможно ли отнять число в PlayerPrefs.SetInt?

Возможно ли отнять число в PlayerPrefs.SetInt?

Возможно ли отнять число в PlayerPrefsSetInt?

101