两个单例相互引用会破坏统一

本文关键字:引用 两个 单例相 | 更新日期: 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时,它工作的原因是静态成员在第一次访问静态成员之前初始化,并且在调用静态构造函数(如果有的话)之前初始化。