我可以用这种方式为所有派生的单身人士定义一个抽象类吗?

Age*_*ire 12 .net c# singleton abstract-class c#-4.0

这是我的抽象类,每次我想创建一个Singleton时都必须派生它:

public abstract class Singleton<T> where T : Singleton<T>
{
    private static readonly Lazy<T> _instance = new Lazy<T>(() =>
    {
        var constructor = typeof(T).GetConstructor(BindingFlags.NonPublic |
            BindingFlags.Instance, null, new Type[0], null);

        return (T)constructor.Invoke(null);
    });
    public static T Instance { get { return _instance.Value; } }
    public Singleton() { }
}
Run Code Online (Sandbox Code Playgroud)

所以,每次我需要遵循Singleton设计模式时,我都可以这样做:

sealed class Server : Singleton<Server>
{
    private Server() { }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是完全正确的,如果没有,为什么?

编辑:

  • 在派生类示例上添加了私有构造函数并在抽象基础上调用.

编辑:

  • 重写类型参数初始化.

Sae*_*iri 8

不,你不能,因为当你想要使用时,new T()你应该有一个公共构造函数,它与单例定义不同.因为在单例中你应该有一个私有构造函数,在这种情况下(公共一个),每个人都可以创建对象的新实例,而不是单例.


Rit*_*ton 3

自我实现的单例是一种反模式。如果您只实现一个工厂,那么继承并将类锁定为特定形式的需要就消失了:

public class Server {} //Not coupled to any inheritance hierarchy.

public class Factory
{
    private readonly Lazy<Server> _server = new Lazy<Server>(() => new Server());

    public Server Server { get { return _server.Value; } }
}
Run Code Online (Sandbox Code Playgroud)

然而,您实际上是在使用工厂作为服务定位器,并且服务定位器也被认为是一种反模式,因为您可以轻松地使用 DI 将 Server 实例注入到您的消费类中。

public class MyServerConsumer
{
    public MyServerConsumer(Server server)
    {
      //Do stuff.      
    }
}
Run Code Online (Sandbox Code Playgroud)

温莎风格注册:

 ... 
 Component.For<Server>();
 ...
Run Code Online (Sandbox Code Playgroud)

请注意,从未提到过“单身人士”这个词?您仍然得到“对象的单个实例”,但您不必编写代码来维护这种关系,并且您的类从一开始就不会受到“单例”概念的约束和破坏