§ October 4, 2006
A Generic Singleton Pattern in C#
I don't know why its never occured to me to implement the singleton pattern as a generic type before. I've always just created the singleton pattern as part of my class (not that we're talking about a lot of coding here), but it occured to me that a singleton could be a lot easier to implement and spot if I used a generic type.
Here is my generic Singleton class:
Now, instead of implementing this same thing in every single class you want to act as a singleton, you simply use the generic definition: Foo.Instance.Whatever turns into Singleton<Foo>.Instance.Whatever.
Update: I've updated this implementation from using a mutex to using a simple lock (double checked) object. A mutex is pointless for a singleton (which I may go into in another article at some later time) as you can never have 2 separate execution contexts accessing one singleton anyway (which is where you would need a mutex over a simple lock object), and I changed the where T : new() to where T : class and changed the instantiation to use reflection to call the private default constructor instead, which I think is the correct implementation.
I don't know why its never occured to me to implement the singleton pattern as a generic type before. I've always just created the singleton pattern as part of my class (not that we're talking about a lot of coding here), but it occured to me that a singleton could be a lot easier to implement and spot if I used a generic type.
Here is my generic Singleton class:
public class Singleton<T> where T : class { static object SyncRoot = new object( ); static T instance; public static T Instance { get { if ( instance == null ) { lock ( SyncRoot ) { if ( instance == null ) { ConstructorInfo ci = typeof( T ).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null ); if ( ci == null ) { throw new InvalidOperationException( "class must contain a private constructor" ); } instance = (T)ci.Invoke( null ); } } } return instance; } } }
Now, instead of implementing this same thing in every single class you want to act as a singleton, you simply use the generic definition: Foo.Instance.Whatever turns into Singleton<Foo>.Instance.Whatever.
Update: I've updated this implementation from using a mutex to using a simple lock (double checked) object. A mutex is pointless for a singleton (which I may go into in another article at some later time) as you can never have 2 separate execution contexts accessing one singleton anyway (which is where you would need a mutex over a simple lock object), and I changed the where T : new() to where T : class and changed the instantiation to use reflection to call the private default constructor instead, which I think is the correct implementation.
Posted 19 years, 6 months ago on October 4, 2006
© 2003 - 2024 NullFX