Ошибка переполнения стека при создании объекта - PullRequest
0 голосов
/ 18 января 2019

Я получил консольное приложение, в котором я получаю ошибку переполнения стека при запуске приложения.

Основная программа

class Program
{
    public static void Main(string[] args)
    {
        Town town = new Town();

        Console.Write("Press any key to continue . . . ");
        Console.ReadKey(true);
    }
}

Моя проблема в том, что я хочу присвоить всем зданиям в цикле foreach Список всех названий зданий, но он не работает, я полагаю, потому что он вызывает переполнение стека, и я не знаю почему. Есть ли лучший способ сделать это, или я все-таки что-то не так делаю?

public class Town
{
    public Town town = new Town();
    public List<Buildings> buildings = new List<Buildings>();

    private List<string> buildingNames = new List<string>() {"Town_Hall", "Market", "Residences", "Mortician", "Bank", "Hotel", "Tailor", "Gunsmith", "General_Store", "Sheriff", "Well", "Gate", "Wall"};

    public void ResetTown()
    {
        foreach (Buildings building in town)
        {
            int i = 0;
            i++;
            building.Name = buildingNames[i].ToString();
            building.Level = 0;
        }
    }

    public IEnumerator<Buildings> GetEnumerator() 
    { 
        return buildings.GetEnumerator(); 
    } 
}


public class Buildings
{
    public string Name {get; set;}
    public int Level {get; set;}
}

Ответы [ 3 ]

0 голосов
/ 18 января 2019

Это рекурсивно, каждый раз, когда вы создаете город, вы создаете город, он продолжается вечно, вселенная рушится в особенность

public class Town
{
    public Town town = new Town()
    ...

Что вы, вероятно, хотите, это

public class Town
{
    // when you auto initialise a property, 
    // it gets created when your create the class
    // this is your recursion, lets get rid of it as its completely
    // unneeded 
    //public Town town = new Town();
    public List<Buildings> buildings = new List<Buildings>();

    private List<string> buildingNames = new List<string>() {"Town_Hall", "Market", "Residences", "Mortician", "Bank", "Hotel", "Tailor", "Gunsmith", "General_Store", "Sheriff", "Well", "Gate", "Wall"};

    public void ResetTown()
    {
        // notice now we dont need a reference to town
        // we "are" the town
        foreach (Buildings building in this)
        {
            int i = 0;
            i++;
            building.Name = buildingNames[i].ToString();
            building.Level = 0;
        }
    }

    public IEnumerator<Buildings> GetEnumerator() 
    { 
        return buildings.GetEnumerator(); 
    } 
}

Использование такое же

public static void Main(string[] args)
{
    Town town = new Town();
}
0 голосов
/ 18 января 2019

Вы также можете использовать это. Пометить Building как класс вместо Buildings. Отделите здания от города и добавьте их через конструктор:

Кроме того, ваш int i = 0; i++ содержит ошибки и может вызвать IndexOutOfRangeException .

public class Town
{
    private List<Building> buildings;
    private List<string> buildingNames = new List<string>() {"Town_Hall", "Market", "Residences", "Mortician", "Bank", "Hotel", "Tailor", "Gunsmith", "General_Store", "Sheriff", "Well", "Gate", "Wall"};

    public Town(List<Building> buildings)
    {
       this.buildings = buildings;
    }

    public void ResetTown()
    {
        int i = 0;
        foreach (Building building in buildings)
        {
            building.Name = buildingNames[i].ToString();
            building.Level = 0;
            i++;
        }
    }

    public IEnumerator<Building> GetEnumerator() 
    { 
        return buildings.GetEnumerator(); 
    } 
}

public class Building
{
    public string Name {get; set;}
    public int Level {get; set;}
}
0 голосов
/ 18 января 2019

Посмотрите на конструктор Town, вы увидите, что он создает экземпляр Town, который снова вызывает себя, тем самым вводя бесконечный цикл.

Другими словами, каждый экземпляр Town содержит переменную Town, которая, в свою очередь, содержит переменную Town, для создания одного экземпляра Town потребуется миллиард лет и миллиард гигабайт ...

public Town town = new Town(); 

По сути то же самое, что и

Public Town town;
Public Town()
{
    town = new Town(); //constructor calls itself
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...