Implementing singleton inheritable class in C# [duplicate]

假装没事ソ 提交于 2019-12-07 03:35:40

问题


I found that in C# you can implement a Singleton class, as follows:

class Singleton
{

    private static Singleton _instance;

    public static Singleton Instance
    {
        get { return _instance ?? (_instance = new Singleton()); }
    }

    protected Singleton() { }
}

Which works for instances of type Singleton, i.e:

var a = Singleton.Instance;
var b = Singleton.Instance;
Console.WriteLine(ReferenceEquals(a, b)); //Prints True.

But what if I want that derived classes of Singleton also follow the Singleton pattern, i.e:

class A:Singleton
{ ... }
A a = A.Instance;

In this case the static member Instance is accessed by Singleton class and creates a Singleton instance, which isn't the objective. Besides, there are two main problems with this solution:

  • The derived class can implement its own constructor and loose the Singleton Pattern.
  • If there is another instance of Singleton then the derived class is going to reference that less-derived instance

My question is: Is there another way to implement a Singleton class in C# ensuring that derived class are also singleton?


回答1:


Ignoring the usual "Don't use a Singleton, look at your design." arguments, you could conceivably implement one as thusly (assuming your derived classes have default constructors):

public abstract class Singleton<T> where T : class, new()
{
    private static T _instance;

    public static T GetInstance()
    {
        if(_instance == null)
            _instance = new T();
        return _instance;
    }
}

And derive thusly:

public class SingletonA : Singleton<SingletonA> { /* .... */ }
public class SingletonB : Singleton<SingletonB> { /* .... */ }

But, I really don't advocate this singleton approach personally. They do have their (rare) uses, but they can turn out to be more of a pain in the bum - turning in to glorified global variable containers.

Also, be mindful of thread-safety.




回答2:


My question is: Is there another way to implement a Singleton class in C# ensuring that derived class are also singleton?

Well, you could have some sort of check within the constructor that:

  • The actual type of this is sealed
  • The actual type of this is a direct subclass of Singleton
  • No other instance of that type has been created (by keeping a HashSet<Type>)

However, it seems rather pointless. What is your base class actually meant to achieve?

The singleton pattern is easy to implement properly (which your example doesn't, by the way - it's not thread safe) so why have the base class? The base class itself wouldn't be a singleton (there would potentially be many instances - one per subclass) so what's the benefit?

It seems to me that "I'm a singleton for the actual type of the object" isn't an appropriate basis for inheritance in the first place, and frankly I'd try to avoid the singleton pattern as far as possible anyway.

If you really want a base class, it should be because there's some common functionality that all the subclasses naturally inherit. That's unlikely to be inherently to do with whether those subclasses are singletons.



来源:https://stackoverflow.com/questions/16865413/implementing-singleton-inheritable-class-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!