Singleton Pattern for C#

Singleton Pattern for C#

Typically a singleton isn't a static class - a singleton will give you a single instance of a class.

I don't know what examples you've seen, but usually the singleton pattern can be really simple in C#:

public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
static Singleton() {} // Make sure it's truly lazy
private Singleton() {} // Prevent instantiation outside

public static Singleton Instance { get { return instance; } }
}

That's not difficult.

The advantage of a singleton over static members is that the class can implement interfaces etc. Sometimes that's useful - but other times, static members would indeed do just as well. Additionally, it's usually easier to move from a singleton to a non-singleton later, e.g. passing in the singleton as a "configuration" object to dependency classes, rather than those dependency classes making direct static calls.

Personally I'd try to avoid using singletons where possible - they make testing harder, apart from anything else. They can occasionally be useful though.

What is a singleton in C#?

A singleton is a class which only allows one instance of itself to be created - and gives simple, easy access to said instance. The singleton premise is a pattern across software development.

There is a C# implementation "Implementing the Singleton Pattern in C#" covering most of what you need to know - including some good advice regarding thread safety.

To be honest, It's very rare that you need to implement a singleton - in my opinion it should be one of those things you should be aware of, even if it's not used too often.

Singleton pattern - a simplified implementation?

On site https://sharplab.io you can look at IL code, in both cases IL code are similar. So this should work same way.

Thread Safe C# Singleton Pattern

Performing the lock is terribly expensive when compared to the simple pointer check instance != null.

The pattern you see here is called double-checked locking. Its purpose is to avoid the expensive lock operation which is only going to be needed once (when the singleton is first accessed). The implementation is such because it also has to ensure that when the singleton is initialized there will be no bugs resulting from thread race conditions.

Think of it this way: a bare null check (without a lock) is guaranteed to give you a correct usable answer only when that answer is "yes, the object is already constructed". But if the answer is "not constructed yet" then you don't have enough information because what you really wanted to know is that it's "not constructed yet and no other thread is intending to construct it shortly". So you use the outer check as a very quick initial test and you initiate the proper, bug-free but "expensive" procedure (lock then check) only if the answer is "no".

The above implementation is good enough for most cases, but at this point it's a good idea to go and read Jon Skeet's article on singletons in C# which also evaluates other alternatives.

C# Singleton Pattern

I wondered if there was a way to set up an abstract class to minimise my code repetition a bit

No, there isn't. As soon as you've got an abstract class, you've got a class which can be instantiated multiple times. I've seen various people try to do something like this, but the end result is either not a singleton or is more complicated than just doing what you're already doing.

Is what I'm trying to do even possible? Or should I just keep doing what I'm doing and not worry about a base singleton class?

You shouldn't try to create a base singleton class - but if I were you I'd try to stop using quite so many singletons in the first place. The singleton pattern is very easily overused, and it's tantamount to an anti-pattern. See if you can refactor towards dependency injection, using a configuration which happens to create only one instance of each of these classes, but where that's a matter of configuration rather than enforced by the class itself.

Aside from anything else, unit testing involving singletons tends to be a pain, simply because it's global state which needs cleaning up between tests etc.

Static constructor - Singleton Design pattern in c#

All that the private constructor is really doing in this case is preventing anything outside of the class from instantiating an instance of class Singleton, which is almost certainly intentional as a singleton should only have a single instance.

Static class constructors are run once for a type, at an unknown time, before the type, or any of it's static members, is to be utilized. Static fields are initialized before the static constructor would be run.

So, I suppose you could replace the constructor with a static one, but that would then give you the implicit parameter-less constructor on the Singleton Type, which would allow anyone to instantiate an instance, which is likely at odds with why you are using the singleton pattern in the first place. It also wouldn't change anything about how your class was being constructed, really, so why do it?

Take the following class as an example:

public class Test { }

Under the covers, because there is no declared constructor, the C# compiler implicitly adds a parameterless, public constructor to the class, allowing consumers to create an instance.

public class Program {
public static void Main() {
var test = new Test();
}
}

This is all fine and good if you want to be able to make instances of your class. The singleton pattern intends to only provide a single instance of a type to the consumers. We could add this static instance to our test type like so:

public class Test { public static Test Instance {get;} = new Test(); }

and we would be able to get this static instance like so:

public class Program {
public static void Main() {
var test = Test.Instance; // good
var other = new Test(); // less than ideal
}
}

So we are providing access to our singleton object through it's instance field, as expected, but we can still create instances of the singleton type, which is less good, as it goes against the purpose of a singleton (namely, having only a single shared instance.)

So we add a private, parameterless constructor to the type.

public class Test { 
private Test() {}
public static Test Instance {get;} = new Test();
}

Adding a constructor to a type will cause the C# compiler not to add an implicit public parameter-less constructor. Making it private allows it to be accessed within the class scope, which is used for instantiating our instance property, and prevents anything else from instantiating the object. The end result being:

public class Program {
public static void Main() {
var test = Test.Instance; // good
var other = new Test(); // Compile time error
}
}

Your singleton object now prevents other instances of the class from being instantiated, and the only way to use it is through the instance property as intended.

using C# interface to create a Manager class that implementing a singleton pattern, but the child manager class does not have a singleton pattern

Your Manager class derives from Singleton<Manager>, which provides a method to get an instance of Manager, Singleton<Manager>.GetInstance(). Your GameManager now inherits from Manager and with that from Singleton<Manager>.

As you already do in GameManager.Initialize(), you can set the manager singleton with SetSingleton, and it accepts the GameManager as argument, because it expects a Manager, which your GameManager ist.

But your GameManager still only implements Singleton<Manager>, meaning the GetInstance() method can only return a Manager, not a GameManager, although the manager you get back is actually your GameManager. You could cast that now to a GameManager and it would work, although that would be a rather unclean solution.

That said: I think trying to enforce a singleton pattern via interface is not a clean solution, as was pointed out in comments already. If you want to work with singleton manager instances, I would advise you to look into dependency injection. For Unity I can highly recommend Zenject. If you never worked with DI before it takes a moment to get used to, but used correctly it makes your code cleaner; I for one would not want to miss it in my projects.

how to use interface with singleton class

Although it's hard to tell what exactly you are referring to, one pattern you might be referring to is the Multiton pattern, where you manage a map of named instances as key-value pairs.

That's basically a factory, but each instance is only created once:

I've modified the Wikipedia example a bit to show that you can even derive from a singleton class, as long as your concrete implementations are private and within the original class:

class FooMultiton
{
private static readonly Dictionary<object, FooMultiton> _instances =
new Dictionary<object, FooMultiton>();

// this is the classic good old singleton trick (prevent direct instantiation)
private FooMultiton()
{ }

// you can also have private concrete implementations,
// invisible to the outside world
private class ConcreteFooMultitonOne : FooMultiton
{ }

public static FooMultiton GetInstance(object key)
{
lock (_instances)
{
FooMultiton instance;

// if it doesn't exist, create it and store it
if (!_instances.TryGetValue(key, out instance))
{
// at this point, you can create a derived class instance
instance = new ConcreteFooMultitonOne();
_instances.Add(key, instance);
}

// always return the same ("singleton") instance for this key
return instance;
}
}
}

Also, generally, if a singleton is not a static class, it can implement any interface you want. The only thing that a singleton pattern prevents is instantiation of multiple instances of a singleton class, but that doesn't mean you cannot completely replace the implementation with something else.

For example, if you have a singleton which is not a static class:

interface ICanTalk
{
string Talk();
}

class Singleton : ICanTalk
{
private Singleton() { }

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

public string Talk()
{ return "this is a singleton"; }
}

You can also have a number of different implementations:

class OtherInstance : ICanTalk
{
public string Talk()
{ return "this is something else"; }
}

Then you are free to choose any implementation you want, but get only a single instance of the Singleton class:

ICanTalk item;

item = Singleton.Instance;
item = new OtherInstance();
item = new YetAnotherInstance();


Related Topics



Leave a reply



Submit