自引用单例中的共享实例

时间:2019-07-10 03:23:02

标签: c# singleton self-reference

当我尝试如下定义自引用Singleton时:

class Singleton<T> where T : Singleton<T> { protected static T singletonInstance; ... }

当我使用像这样的非泛型类派生单例类时,实施单例类工作正常:

class Derived : Singleton<Derived> { ... }

但是,当我尝试通过像这样的通用类派生单例时:

class Derived<T> : Singleton<Derived<T>> { ... }

然后实现通用类:

class DerivedChildA : Derived<int> { ... }
class DerivedChildB : Derived<int> { ... }

在两个子类之间共享的只有一个DerivedChildA类型的单例实例,而不是获取DerivedChildBDerived<int>的单个单例实例。

我宁愿没有DerivedChildADerivedChildB直接从Singleton<T>派生。那么我应该如何修改类声明以获取DerivedChildADerivedChildB(即Singleton<DerivedChildA>Singleton<DerivedChildB>)的单个单例实例?


编辑:正如Varun所指出的那样,当参数T类型不同时,这种自引用单例方法的确会产生唯一的单例实例,例如with

class DerivedChildC : Derived<string> { ... }
class DerivedChildD : Derived<double> { ... }

但是,我的项目要求DerivedChildADerivedChildB具有完全相同的通用类型Derived<int>,但是很遗憾,我无法更改此要求。 :(

1 个答案:

答案 0 :(得分:0)

让我们了解这里发生了什么。静态字段在所有实型实例之间共享。泛型定义不是真实类型;只要为泛型参数提供了具体的泛型类型参数,就会创建实类型。因此,在这种情况下,只要您说:

: Derived<int>

,或者即使您直接从Singleton继承,也可以:

: Singleton<int>

为通用定义生成类型后,它的静态字段(在您的示例中为实例)将在所有派生类型之间共享

这可以通过一个稍有不同的示例来证明,方法是更改​​通用参数T的参数。因此,如果您有

class DerivedChildA : Derived<int>

class DerivedChildB : Derived<decimal>

您将生成两个单独的实类型作为基数,因此对于A和B的实例,静态Instance字段也将是单独的。