0

I'm getting StackOverflowException when I run below program. My doubt is how this program recursively calling each classes(ArrayTest1, ArrayTest2) fields without executing constructor method?

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        var arraryTest = new ArrayTest1();
    }
}

public class ArrayTest1
{
    ArrayTest2 arrayTest2 = new ArrayTest2();
    public ArrayTest1()
    {
        Console.WriteLine($"{nameof(ArrayTest1)} Class Contructor Executed");
    }
}

public class ArrayTest2
{
    ArrayTest1 arrayTest1 = new ArrayTest1();
    public ArrayTest2()
    {
        Console.WriteLine($"{nameof(ArrayTest2)} Class Contructor Executed");
    }
}
Austin
  • 2,203
  • 3
  • 12
  • 28
Gowtham Raj
  • 103
  • 8
  • 1
    Because you create an infinite chain of ArrayTest1 -> ArrayTest2 -> ArrayTest1 -> ArrayTest2 -> ... – Lesiak Nov 02 '22 at 13:33
  • Perhaps you intended for `ArrayTest1.arrayTest2` and `ArrayTest2.arrayTest1` to be static members? – 41686d6564 stands w. Palestine Nov 02 '22 at 13:37
  • The .NET runtime does not directly support initializing fields like this. The C# compiler solves this by moving the field initialization code into the constructor of the class, before any code you wrote yourself. So it *does* in fact execute the constructors, but the stack overflows before it can get to the Console.WriteLine() statements. – Hans Passant Nov 02 '22 at 13:51

2 Answers2

3

Because you create an infinite chain of ArrayTest1 -> ArrayTest2 -> ArrayTest1 -> ArrayTest2 -> ...

To understand why you are not getting any output, see C# constructor execution order

Important steps in your case (no inheritance involved):

  • Member variables are initialized to default values
  • Variable initializers are executed
  • The constructor bodies are executed

You never reach constructor bodies, as the stack overflow happens in variable initializer

Lesiak
  • 22,088
  • 2
  • 41
  • 65
2

Because when you do this:

new ArrayTest1()

You are creating an instance of ArrayTest1. Which does this:

ArrayTest2 arrayTest2 = new ArrayTest2();

This creates an instance of ArrayTest2. Which does this:

ArrayTest1 arrayTest1 = new ArrayTest1();

This creates an instance of ArrayTest1. Which does this:

ArrayTest2 arrayTest2 = new ArrayTest2();

This creates an instance of ArrayTest2. Which does this:

ArrayTest1 arrayTest1 = new ArrayTest1();

This creates an instance of ArrayTest1...

And so on, indefinitely.


It's not clear what your goal is with the code. But what is clear is that your objects can't mutually depend on one another this way because the simple act of creating an instance of the object results in an infinite recursion.

Given only the code shown, the solution is to simply remove those mutually-dependent fields from the classes, since nothing ever uses them anyway:

public class ArrayTest1
{
    public ArrayTest1()
    {
        Console.WriteLine($"{nameof(ArrayTest1)} Class Contructor Executed");
    }
}

public class ArrayTest2
{
    public ArrayTest2()
    {
        Console.WriteLine($"{nameof(ArrayTest2)} Class Contructor Executed");
    }
}
David
  • 208,112
  • 36
  • 198
  • 279
  • thanks for the reply, I have written this code to test how constructor works. So fields will be execute first? then after only constructors will be called? – Gowtham Raj Nov 02 '22 at 13:54
  • 1
    @GowthamRaj: Whether fields or constructors are performed first, in either case you still have an infinite recursion. I would *guess* that fields are initialized first, and some research on the subject may confirm or deny that. But if you have constructor code which relies on that then you may have brittle code and bugs that are waiting to happen anyway. In any event, remove the recursion. – David Nov 02 '22 at 13:57