两个单例相互引用会破坏统一
本文关键字:引用 两个 单例相 | 更新日期: 2023-09-27 18:18:54
我有以下两个单例:
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;
}
}
}
不幸的是,我没有得到任何错误,但只要我访问我的类Unity3d崩溃的parentState。我也不能在初始化附近设置断点。
当我在实例属性中初始化字段时,它可以工作。当我将字段设置为静态时,它也可以工作,例如:
private static ISomeInterface<anotherClass> parentState = Other.Instance;
谁能解释一下为什么我的第一种方法不起作用?
问题
你通过每次创建一个新实例来创建无限递归,这最终将导致StackOverflowException。这是因为您坚持每个Singleton都有对另一个Singleton的引用。
为什么静态工作
Static不会给你这个问题,因为"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字段初始化。
另一种解决问题的方法
如果你让两个singleton都使用eager实例化而不是lazy实例化,你就不会有这个问题。主动实例化看起来像这样:
public class Singleton
{
private static Singleton instance = new Singleton();
public static Singleton getInstance { get { return instance; } }
}
这是可以工作的,因为它不依赖于谁调用Singleton来创建实例。
通过创建构造函数成员引用彼此的构造函数来创建无限循环:
在MyClass中你有:
private ISomeInterface <anotherClass> parentState = Other.Instance;
在Other Class中你有:
private ISomeInterface <anotherClass> childState = MyClass.Instance;
ie。MyClass创建导致其他创建,导致MyClass创建…等等
当这些成员是static时,它工作的原因是静态成员在第一次访问静态成员之前初始化,并且在调用静态构造函数(如果有的话)之前初始化。