0

I got a console application where I get an Stack Overflow error when starting the application.

Main programm

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

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

My problem is that I want to name all the buildings in the foreach loop with the List of all the building names but it's not working I suppose because it's causing an Stackoverflow and I don't know why. Is there any better way to do this or am I doing something wrong after all somewhere else?

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;}
}
4
  • Did you debug the code? Which code is executing repeatedly? Looks like public Town town = new Town(); is the problem. Why you have that line code? Commented Jan 18, 2019 at 3:16
  • What do you think public Town town = new Town(); does? Commented Jan 18, 2019 at 3:36
  • It creates a new Town object. Commented Jan 18, 2019 at 3:50
  • 1
    "It creates a new Town object." which creates a new Town object, which creates a new Town object, which creates a new Town object, which creates a new Town object, etc. Commented Jan 18, 2019 at 4:27

3 Answers 3

1

Look at Town's constructor, you will see that it creates a Town instance, which calls itself again, thus entering an endless loop.

In order words, each Town instance contains a Town variable, which in turn contains a Town variable, it will take a billion year and a billion GigaBytes... to constructor a single Town instance.

public Town town = new Town(); 

Is essentially the same as

Public Town town;
Public Town()
{
    town = new Town(); //constructor calls itself
 }
Sign up to request clarification or add additional context in comments.

Comments

0

You can use this also. Mark Building as a class instead of Buildings. Decouple the buildings from town and inject it via a constructor:

Also, your int i = 0; i++ has bugs and can cause 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;}
}

Comments

0

It's recursive; each time you create a town, you create a town, it goes on forever, the universe collapses into a singularity:

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

What you probably want is this

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(); 
    } 
}

Usage is the same

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

1 Comment

And how do I use the town in the main program when I don't initialize the object?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.