这就是我编写单例类的方式。
public class MyClass
{
/// <summary>
/// Singleton
/// </summary>
private static MyClass instance;
/// <summary>
/// Singleton access.
/// </summary>
public static MyClass Instance
{
get
{
if (_instance == null)
{
_instance = new MyClass();
}
return _instance;
}
}
private MyClass() { .... }
}
如何创建可重用的单例模式?
单例模式带来了以下挑战。
- 构造函数是
private
或protected
。 - 基类不能实例化继承类。因此,您可以重用通用抽象
MyAbstractSingletonClass
。 - 它必须具有本地只读属性才能获取实例。
问题
我在许多类中使用了这种模式,并且总是必须编写相同的代码。当我需要单例时,如何编写可以重用的东西?
最佳答案
您可以使用 self-referencing generic type constraint 的组合来实现此目的, 和一个“new()”类型约束。
"new"约束确保任何子类都将始终具有无参数构造函数,因此 _instance = new T();
将始终有效。
自引用类型约束确保“实例”静态属性始终返回正确的类型;不是“基本”类型。你的单例基类看起来像这样:
public abstract class SingletonBase<T>
where T : SingletonBase<T>, new()
{
private static T _instance = new T();
public static T Instance
{
get
{
return _instance;
}
}
}
您的子类将如下所示:
public class MyChildSingleton : SingletonBase<MyChildSingleton>
{
//Done!
}
当然,如果你希望你的单例是通用的,你也应该稍微改变你的“创建单例实例”代码,使用“double-check lock”模式,或者Lazy。类,使其成为线程安全的。
重要警告:如果您使用此方法,“new()”约束几乎可以确保您的类始终具有公共(public)的、无参数的构造函数。这意味着如果您的最终用户确实需要,他们总是可以调用 new MyChildSingleton()
,完全绕过您的单例实例。您的单例将是“按照惯例”,而不是严格执行。要解决这个问题需要更多的工程。在上面的场景中,惯例似乎是您应该将静态实例命名为“Default
”而不是“Instance
”。这巧妙地传达了这样一个事实,即您的类提供了一个“建议的”单例实例,但使用它在技术上是可选的。
我做了一些尝试来严格执行单例模式,最终结果是使用反射手动调用私有(private)构造函数。你可以看到我的完整代码尝试 here .
关于c# - 如何抽象一个单例类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16745629/