这是一种(丑陋的)方法。它可能会被简化和改进,但这是我第一次尝试。
其思想是首先使基类成为通用抽象类(如上面的注释中所述),但类型参数被约束为从基类本身派生。这允许基类处理派生类型的单例实例。注意,所有派生类都应该密封,就像任何单例类一样。
接下来,允许使用受保护的构造函数,但需要接受一个特殊类singletonkey的实例,该类是一个经过修改的singleton。派生类可以访问singletonkey类定义,但基类保留对唯一允许的实例的私有控制,从而对所有派生对象的构造进行控制。
第三,基类需要能够调用派生类的构造函数,但这有点棘手。如果您试图调用派生的键化构造函数,编译器会抱怨,因为它不一定存在。解决方案是添加派生类必须初始化的静态委托。因此,任何派生类都需要提供一个简单的初始化方法。在代码中首次尝试访问实例之前,应显式调用此初始化方法,否则将导致运行时错误。
public abstract class Singleton where T : Singleton
{
protected Singleton(SingletonKey key) { }
private static SingletonKey _key;
private static SingletonKey Key
{
get
{
if (_key == null) SingletonKey.Initialize();
return _key;
}
}
protected class SingletonKey
{
private SingletonKey()
{
}
public static void Initialize()
{
if (_key == null)
{
_key = new SingletonKey();
}
}
}
protected static Func Creator;
private static T instance;
public static T Instance
{
get
{
if (instance == null) instance = Creator(Key);
return instance;
}
}
}
public class MySingleton : Singleton
{
public string Name { get; set; }
public static void Initialize()
{
Creator = (key) => new MySingleton(key);
}
protected MySingleton(SingletonKey key) : base(key)
{
}
}