How to Implement a Singleton in C#

How to implement a singleton in C#?

If you are just storing some global values and have some methods that don't need state, you don't need singleton. Just make the class and its properties/methods static.

public static class GlobalSomething
{
public static int NumberOfSomething { get; set; }

public static string MangleString( string someValue )
{
}
}

Singleton is most useful when you have a normal class with state, but you only want one of them. The links that others have provided should be useful in exploring the Singleton pattern.

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.

How to use this Singleton Class in C#?

Your field Messages is not initialized to anything. That is why you are getting the exception. In your class do:

 private List<string> Messages = new List<string>();

You may also look at Thread Safe Singleton implementation by Jon Skeet

EDIT:

Based on the updated question. Your Check and Message are opposite. It should be:

if (Singleton.Instance.HasMessage("12"))
Console.WriteLine("There is a match");
else
Console.WriteLine("NO STRING!!!");

Your method HasMessage returns true if the passed parameter is present in the list and false otherwise.

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.

C# Singleton - Basic Implementation and strategy

Your code has multiple issues:

First, when writing a singleton that has no dependencies to other classes like in your case, it is best practise to have a static readonly field that holds the single instance, but you should instantiate it straight away like so:

private static CurrentMDL_Singleton instance = new CurrentMDL_Singleton();

This is because, whenever you reference a singleton class, you will probably use its instance. Moving the instantiation to a field init moves it into the type loader and therefore makes it thread-safe. In your code, if clients access the Instance property in parallel, you may end up in a race condition and hence with two different instances of a singleton class, which is something that you would typically want to avoid.

Second, your constructor creates an object and does not save it anywhere, hence you can't access it.

Third, there is absolutely no need to have an instance variable holding a singleton instance, because you can always get it from the static instance field. In your case, it is even dangerous because someone could change it to null and you would not notice.

Lastly, you should really reconsider whether it is really a singleton that you need. A singleton pattern is applied to make sure that there is only one instance of a class, usually not because it is easier to query its contents, because it is a dependency that you cannot easily exchange.

How to implement singleton pattern in subclass

You have the singleton implementation correct. Now that you have that, the rest is very much like regular inheritance. Remember that you can reference inherited methods, properties and fields using the "this" operator.

Following closely with your existing code, to set the values of the inherited properties from the sub-class, you need to, for example:

this.upperlimit = 5000;

The question then is where you should set the limit in the sub-class. The constructor would be a likely place to ensure that the upper limit is guaranteed to be set before use. This would look like:

private BronzeState()
{
this.upperlimit = 5000;
}

One thing I will note, although it isn't directly answering the question, is you should consider who you want to be able to change the limits of an AccountState. Right now, your limits can be seen and set by any other class. It seems like you would only want them changeable by the sub-classes.

To do this, you will want to use a protected setter, like so:

public double upperlimit { get; protected set; }

That ensures that the value can be seen by anyone, but can only be set by the parent class or sub-classes.

The full picture would then be:

public class AccountState
{
public double UpperLimit { get; protected set; }
public double LowerLimit { get; protected set; }
}

public class BronzeState : AccountState
{
private BronzeState()
{
this.UpperLimit = 5000;
this.LowerLimit = 1000;
}

public static BronzeState GetInstance()
{
...
}
}

Without knowing too much about the specifics of your scenario, I would also consider using abstract properties in this scenario. For example:

public abstract class AccountState
{
public abstract double UpperLimit { get; }
public abstract double LowerLimit { get; }
}

public class BronzeState : AccountState
{
public override double UpperLimit
{
get { return 5000; }
}

public override double LowerLimit
{
get { return 1000; }
}

public static BronzeState GetInstance()
{
...
}
}

This design has the advantage of forcing the sub-class to define the upper and lower limits, as well as encourages them not to change, if that is so desirable. Choosing which design is better would depend on the broader scenario this is fitting into.


In either of the examples above, to access the values from outside the class would look like:

double limit = BronzeState.GetInstance().UpperLimit;

You can read more about inheritance in C# (including the things I mentioned above) on MSDN.

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.

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.



Related Topics



Leave a reply



Submit