当我尝试如下定义自引用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
类型的单例实例,而不是获取DerivedChildB
和Derived<int>
的单个单例实例。
我宁愿没有DerivedChildA
和DerivedChildB
直接从Singleton<T>
派生。那么我应该如何修改类声明以获取DerivedChildA
和DerivedChildB
(即Singleton<DerivedChildA>
和Singleton<DerivedChildB>
)的单个单例实例?
编辑:正如Varun所指出的那样,当参数T类型不同时,这种自引用单例方法的确会产生唯一的单例实例,例如with
class DerivedChildC : Derived<string> { ... }
class DerivedChildD : Derived<double> { ... }
但是,我的项目要求DerivedChildA
和DerivedChildB
具有完全相同的通用类型Derived<int>
,但是很遗憾,我无法更改此要求。 :(
答案 0 :(得分:0)
让我们了解这里发生了什么。静态字段在所有实型实例之间共享。泛型定义不是真实类型;只要为泛型参数提供了具体的泛型类型参数,就会创建实类型。因此,在这种情况下,只要您说:
: Derived<int>
,或者即使您直接从Singleton继承,也可以:
: Singleton<int>
为通用定义生成类型后,它的静态字段(在您的示例中为实例)将在所有派生类型之间共享
这可以通过一个稍有不同的示例来证明,方法是更改通用参数T的参数。因此,如果您有
class DerivedChildA : Derived<int>
和
class DerivedChildB : Derived<decimal>
您将生成两个单独的实类型作为基数,因此对于A和B的实例,静态Instance字段也将是单独的。