Reputation: 607
I have the following two singletons:
public sealed class MyClass : ISomeInterface<anotherClass>
{
private static MyClass instance = null;
private ISomeInterface <anotherClass> parentState = Other.Instance; // error
private ISomeInterface <anotherClass> childState = null;
private MyClass(){}
public static MyClass Instance
{
get
{
if(instance == null)
{
instance = new MyClass();
}
return instance;
}
}
}
public sealed class Other : ISomeInterface<anotherClass>
{
private static Other instance = null;
private ISomeInterface <anotherClass> parentState = null;
private ISomeInterface <anotherClass> childState = MyClass.Instance;
private Other(){}
public static Other Instance
{
get
{
if(instance == null)
{
instance = new Other();
}
return instance;
}
}
}
Unfortuntately I don't get any error but as soon as I am accessing the parentState of Myclass Unity3d crashes. I also cannot have a break point near the initialization.
When I am initializing the field in the Instance Property it works. It also works when I set the fields static like:
private static ISomeInterface<anotherClass> parentState = Other.Instance;
Can anyone explain me why my first approach does not work?
Upvotes: 1
Views: 707
Reputation: 7824
You are creating infinite recursion by creating a new instance each time, which eventually will lead to a StackOverflowException. This is because you are insisting on each Singleton having a reference to the other.
Static won't give you the problem because "execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class."
-- Static field initialization.
If you make both Singletons use eager instantiation instead of lazy you won't have this problem. Eager instantiation looks like this:
public class Singleton
{
private static Singleton instance = new Singleton();
public static Singleton getInstance { get { return instance; } }
}
This will work because it won't depend on who calls the Singleton to create the instance.
Upvotes: 2
Reputation: 681
You have an infinite loop by constructor member creation referencing eachothers constructors:
In MyClass you have:
private ISomeInterface <anotherClass> parentState = Other.Instance;
In Other Class you have:
private ISomeInterface <anotherClass> childState = MyClass.Instance;
ie. MyClass creation causes Other creation, causes MyClass creation...etc.
The reason it works when these members are static is that static members are initialized before the static member is accessed for the first time and before the static constructor, if there is one, is called.
Upvotes: 1