I need to determine if a member T of class T is a static member, in the constructor. I expect this will involve checking some attributes of "this", but I haven't been able to determine what to look for.
public class Thing
{
public static readonly List<Thing> ListOfStaticThings = new();
public static readonly Thing StaticThing1 = new ("StaticThing1");
public static readonly Thing StaticThing2 = new ("StaticThing2");
public static readonly Thing StaticThing3 = new ("StaticThing3");
public Thing NonStaticThing = new("NonStaticThing");
public string Name { get; set; }
private Thing(string name)
{
Name = name;
if(this.IsStatic) //how to determine if the thing being constructed is static?
{ ListOfStaticThings.Add(this);}
}
}
How do I identify if the Static attribute is applied to this?
*** UPDATED ***
In this example, both StaticThing and NonStaticThing will be constructed using the private constructor. However, only the StaticThing should be added to the ListOfStaticThings when constructed. The full implementation will have 20+ static readonly fields of the class type.
I've already verified that the ListOfStaticThings will contain the StaticThing.
The ListOfStaticThings has multiple uses. This is on the path to Enumeration Classes, with this list containing all the possible Things (such as account statuses) permitted by the class. In addition, the ListOfStaticThings can be passed to EFCore.HasData to seed the data in the table. It can also be used for data validation in unit testing because it contains all the data and is persisted in the model.
However, all those use cases are beyond the scope of this question. The piece I'm looking for is how to identify if the "this" being constructed is static so I can add it to the ListOfStaticThings. I want StaticThing1, 2 & 3 to be in the list, but not NonStaticThing.
*** Final Update ***
As pointed out by McAden's answer, this is not necessary because the non-static member of T cannot be added to class T without causing an infinite recursion overflow. Since only static members of T can be added, there is no need to determine if they are also static in the constructor.
I think you're going about it the wrong way - all static members should be initialized either in the property itself or in a static constructor, so I would do it this way:
public class Thing
{
public static readonly List<Thing> ListOfStaticThings;
public static readonly Thing StaticThing1 = new Thing("StaticThing1");
public static readonly Thing StaticThing2 = new Thing("StaticThing2");
public static readonly Thing StaticThing3 = new Thing("StaticThing3");
// public Thing NonStaticThing = new("NonStaticThing");
public string Name { get; set; }
private Thing(string name)
{
Name = name;
}
static Thing()
{
ListOfStaticThings = new List<Thing> {
StaticThing1,
StaticThing2,
StaticThing3
};
}
}
Now the instance constructor doesn't need to know if it's a "static" instance or not.
However, to be safe (meaning not rely on the order of initializers), I would also crate the static instances in the static constructor:
public class Thing
{
public static readonly List<Thing> ListOfStaticThings;
public static readonly Thing StaticThing1;
public static readonly Thing StaticThing2;
public static readonly Thing StaticThing3;
public string Name { get; set; }
private Thing(string name)
{
Name = name;
}
static Thing()
{
ListOfStaticThings = new List<Thing> {
StaticThing1 = new Thing("StaticThing1"),
StaticThing2 = new Thing("StaticThing2"),
StaticThing3 = new Thing("StaticThing3")
};
}
}
Now, if you need to know if it's "static" for some other reason, then I would create another private constructor that takes a static flag:
private Thing(string name, bool isStatic=False) : this(name)
{
if (isStatic) {
// Do different stuff for a "static" instance
}
}
but I would not put logic there to "add itself" to a static list - that can be accomplished more cleanly another way.
how [do I] prevent non-static members being added to the list
If you want to make the list immutable, then you could either expose it as an immutable type or interface like 'IEnumerable', or you could just
generate the list on the fly with a static property getter:
public static IEnumerable<Thing> ListOfStaticThings {
get {
return new List<Thing> {
StaticThing1,
StaticThing2,
StaticThing3
};
}
}
Updated Answer:
In OP's very specific preferred approach there's no point. The public Thing NonStaticThing = new("NonStaticThing"); will result in a StackOverflowException as each child will try to create another child infinitely.
In general, however, my advice to anybody trying to do something "statically" and otherwise "not" would be to use a static constructor for static things.
Original Answer based upon un-edited question:
Order of operations - The static field will be assigned before anything else outside that class can call the constructor on that class and the constructor for setting that static readonly field will be called before the static field is actually assigned. Simply check to see if the static field is null in your constructor.
private static void Main(string[] args)
{
var test = new Thing();
Console.WriteLine(test.IsStaticInstance); // False
Console.WriteLine(Thing.Instance.IsStaticInstance); // True
}
public class Thing
{
public static readonly Thing Instance = new Thing();
public Thing()
{
IsStaticInstance = Instance == null;
}
public bool IsStaticInstance { get; }
}
I want to get the Lazy instance in another class the problem is that the T type is only set in the main class
the first class where the instance is is this:
public class singleton<T> where T : class, new()
{
private readonly static Lazy<T> val = new Lazy<T>(() => new T());
public static T instance { get { return val.Value; } }
public int UserID {get;set;}
}
now I have a other class for all user datas
public class User
{
public string Name()
{
return data.GetUserFromID(singleton.instance.UserID)
}
}
the singleton is not working because I need the Argument but the T is only in the main class
public class main : singleton<main>
{
public main()
{
UserID = 5;
}
}
EDIT
how do I get the ID from the singleton class inside another class like this
singleton file
public class singleton<T> where T : class, new()
{
private readonly static Lazy<T> val = new Lazy<T>(() => new T());
public static T instance { get { return val.Value; } }
public int UserID {get;set;}
private singleton() {
Datas.UserID = UserID;
}
}
another file
public class Datas {
public static int UserID {get;set;}
}
the singleton is not working because I need the Argument but the T is only in the main class
All you need do is change your code from:
public class User {
public string Name() {
return data.GetUserFromID(singleton.instance.UserID)
}
}
...to specifying the generic type argument:
public class User
{
public string Name()
{
var m = singleton<main>.instance;
Console.WriteLine($"Inside User.Name, m.UserId = {m.UserID}");
return "todo";
}
}
This is required because your client code is accessing the generic base directly. Had you encapsulated it into a factory manager or similar, clients would not need to specify the type.
Here is a little test harness
private void Run()
{
var x = singleton<main>.instance;
Console.WriteLine($"x.UserId = {x.UserID}");
var y = singleton<main>.instance;
Console.WriteLine($"y.UserId = {y.UserID}");
x.UserID++;
Console.WriteLine($"x.UserId = {x.UserID}");
Console.WriteLine($"y.UserId = {y.UserID}");
var user = new User();
Console.WriteLine($"User.Name = {user.Name()}");
var mp = MissPiggy.Instance;
}
Which produces the following results. Note how changing properies on two different variables modifies the same singleton.
There are a few problems too with how you are implementing singletons. A singleton class should have a private constructor and it should be the one managing lifetimes and not a secondary class.
e.g.
public sealed class MissPiggy
{
private static Lazy<MissPiggy> _instance = new Lazy<MissPiggy>(() => new MissPiggy());
private MissPiggy()
{
}
public static MissPiggy Instance
{
get { return _instance.Value; }
}
}
singleton<t> is a generic type - you can't refer to it without a generic type parameter.
Under the hood, it's actually generating new types.
So when you do this:
var mainSingleton = singleton<main>.instance;
It's actually creating a new type which looks like this:
public class NewGenericTypeWithWeirdName
{
private readonly static Lazy<main> val = new Lazy<main>(() => new main());
public static main instance { get { return val.Value; } }
public int UserID { get; set; }
}
...and if you declare var otherSingleton = singleton<SomethingElse>.instance; then it does the same thing - it creates another type, just like above, except T is replaced with SomethingElse.
That's why you can't do this:
singleton.instance.UserID
Because the compiler doesn't know which type you're referring to. Is it the type it generated for singleton<main>, or is it the type generated for singleton<SomethingElse>? They're actually different types, which means the static properties - including UserID, will be different for each of them.
You could do this:
return data.GetUserFromID(singleton<main>.instance.UserID);
^^^^^^
...because now you're telling it the actual type - it's singleton<main>.
Just to clarify, unless the class has a private constructor and no non-private constructors, it isn't a singleton.
You can do this:
var mainSingleton = singleton<main>.instance;
and it will always return the same instance of main.
But you can also do this:
var m1 = new singleton<main>();
var m2 = new singleton<main>();
You can create multiple instances, so it's not a singleton. To fix this, add a private constructor to singleton:
private singleton() {}
Now the constructor can only be called from within the class. That means the only way to get an instance is to call instance. Every time you do that you'll get the same instance, so now it really is a singleton.
I wanted to use a static constructor in derived classes to register object constructor lambdas for those classes to be called when passing a certain Type object.
Since a static constructor is only called just before the first object of that class is created BUT I want to use the result of the static constructor to determine what kind of object to create, this mechanism fails, the constructor lambda is not found.
Is there any way out of this?
public abstract class Cacheable
{
// ... details do not matter ...
}
public class Series: Cacheable
{
// ... details do not matter ...
}
public abstract class CacheableViewForm
{
static Dictionary<Type, Func<CacheableViewForm>> cacheableViewFormConstructors = new Dictionary<Type, Func<CacheableViewForm>>();
protected static void Register<CacheableViewFormClass, CacheableClass>()
where CacheableViewFormClass: CacheableViewForm, new()
where CacheableClass: Cacheable
{
cacheableViewFormConstructors[typeof(CacheableClass)] = (() => new CacheableViewFormClass());
}
public static CacheableViewForm CreateFromTargetType(Type cacheableType)
{
return cacheableViewFormConstructors[cacheableType]();
}
// ... details do not matter ...
}
public class SeriesViewForm: CacheableViewForm
{
static SeriesViewForm() {Register<SeriesViewForm, Series>();}
// ... details do not matter ...
}
// fails because CacheableViewForm.Register<> has not been executed yet!
CacheableViewForm newForm = CacheableViewForm.CreateFromTargetType(typeof(Series));
My solution is to move initialization (from the static constructor of the derived classes) to the static constructor of the base class (which gets called automatically before executing my first call to the CreateFromTargetType method) and using reflection in there to examine the derived classes. In the derived classes I defined static methods (TargetType) which return the specific Type they are operating on.
Neither elegant nor compact, and certainly not super fast, but it allows me to keep the association between derived class (e.g. SeriesViewForm) and the data type it operates on (typeof(Series)) close together (in the same class definition).
public abstract class CacheableViewForm: Form
{
static Dictionary<Type, Func<CacheableViewForm>> CacheableViewFormConstructors = new Dictionary<Type, Func<CacheableViewForm>>();
static CacheableViewForm()
{
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach(Assembly assembly in allAssemblies)
{
Type[] cacheableViewFormTypes = assembly.GetExportedTypes().Where(t => typeof(CacheableViewForm).IsAssignableFrom(t) && t != typeof(CacheableViewForm)).ToArray();
foreach (Type cacheableViewFormType in cacheableViewFormTypes)
{
MethodInfo mi = cacheableViewFormType.GetMethod("TargetType");
Type cacheableType = (Type)mi.Invoke(null, null);
Func<CacheableViewForm> ctorDelegate = (() => (CacheableViewForm)(Activator.CreateInstance(cacheableViewFormType)));
CacheableViewFormConstructors[cacheableType] = ctorDelegate;
}
}
}
public static CacheableViewForm CreateFromTargetType(Type cacheableType)
{
return CacheableViewFormConstructors[cacheableType]();
}
}
public class SeriesViewForm: CacheableViewForm
{
public static Type TargetType() {return typeof(Series);}
// ...
}
So I have a static class with a list declared as one of it's members, and I populate the list in a function lets say it's called PopulateList(). Is it possible to modify the list in another function without:
1) Calling it as a parameter
2) Instantiating it in a constructer (Trying to keep the class static. I'm working off of a template so I can't really change the structure of the classes)
Without somehow instantiating though, I will obviously receive null exceptions, so I was wondering if there is a 3rd way to do this.
public Static class MyClass{
static public List<String> m_SuiteFileNameList2=null;
public static bool Function1(inp){
//m_SuiteFileNameList2 stuff
}
public static void Function2(){
//m_SuiteFileNameList2 other stuff
}
}
You can either use a static constructor, or static initialization. It will allow you to keep your class static, but will ensure that the list is always defined:
static class MyClass
{
static MyClass()
{
MyList = new List<Whatever>();
}
// etc
}
or
static class MyClass
{
public static List<Whatever> MyList = new List<Whatever>();
}
Another option is to add a null check to every usage of the list:
public static void MyMethod()
{
if (MyList == null)
{
MyList = new List<Whatever>();
}
//etc
}
I would call a function called 'Initialize' which is static and takes care of your static members.
Though I would recommend against static members if possible.
Why?
They can lead to head aches (yes, that hurts)
Their behaviour in memory allocation is different (How is memory allocated for a static variable?)
code snippet
public static class YourClass
{
public static List<string> YourList;
public static void InitializeList()
{
YourList = new List<string>();
YourList.Add("hello");
YourList.Add("how");
YourList.Add("are");
YourList.Add("you?");
}
}
Call your Initialize-Function from outside:
YourClass.InitializeList();
EDIT: Given your code , you can also do it this way:
public Static class MyClass{
static public List<String> m_SuiteFileNameList2=null;
public static bool Function1(inp){
if(m_SuiteFileNameList2 == null)
{ m_SuiteFileNameList2 = new List<String>();}
//m_SuiteFileNameList2 stuff
}
public static void Function2(){
if(m_SuiteFileNameList2 == null)
{ m_SuiteFileNameList2 = new List<String>();}
//m_SuiteFileNameList2 other stuff
}
}
I have the following C# singleton pattern, is there any way of improving it?
public class Singleton<T> where T : class, new()
{
private static object _syncobj = new object();
private static volatile T _instance = null;
public static T Instance
{
get
{
if (_instance == null)
{
lock (_syncobj)
{
if (_instance == null)
{
_instance = new T();
}
}
}
return _instance;
}
}
public Singleton()
{ }
}
Preferred usage example:
class Foo : Singleton<Foo>
{
}
Related:
An obvious singleton implementation for .NET?
According to Jon Skeet in Implementing the Singleton Pattern in C# the code you posted is actually considered as bad code, because it appears broken when checked against the ECMA CLI standard.
Also watch out: everytime you instantiate your object with a new type of T, it becomes another instance; it doesn't get reflected in your original singleton.
This code won't compile, you need "class" constraint on T.
Also, this code requires public constructor on target class, which is not good for singleton, because you can't control at compile time that you obtain (single) instance only via Instance property (or field). If you don't have any other static members except Instance, you are ok to go with just this:
class Foo
{
public static readonly Instance = new Foo();
private Foo() {}
static Foo() {}
}
It is thread safe (guaranteed by CLR) and lazy (instance is created with first access to type). For more discussion about BeforeFieldInit and why we need static constructor here, see https://csharpindepth.com/articles/BeforeFieldInit.
If you want to have other public static members on type, but create object only on access to Instance, you may create nested type, like in https://csharpindepth.com/articles/Singleton
Courtesy of Judith Bishop, http://patterns.cs.up.ac.za/
This singleton pattern implementation ensures lazy initialisation.
// Singleton PatternJudith Bishop Nov 2007
// Generic version
public class Singleton<T> where T : class, new()
{
Singleton() { }
class SingletonCreator
{
static SingletonCreator() { }
// Private object instantiated with private constructor
internal static readonly T instance = new T();
}
public static T UniqueInstance
{
get { return SingletonCreator.instance; }
}
}
This is my point using .NET 4
public class Singleton<T> where T : class, new()
{
Singleton (){}
private static readonly Lazy<T> instance = new Lazy<T>(()=> new T());
public static T Instance { get { return instance.Value; } }
}
I don't think that you really want to "burn your base class" so that you can save 2 lines of code. You don't really need a base class to implement singleton.
Whenever you need a singleton, just do this:
class MyConcreteClass
{
#region Singleton Implementation
public static readonly Instance = new MyConcreteClass();
private MyConcreteClass(){}
#endregion
/// ...
}
More details on this answer on a different thread : How to implement a singleton in C#?
However the thread doesn't use generic.
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton(){}
public static Singleton Instance
{
get
{
return instance;
}
}
}
There's no ambiguity in .NET around initialization order; but this raises threading issues.
:/ The generic "singleton" pattern by Judith Bishop seems kinda flawed, its always possible to create several instances of type T as the constructor must be public to use it in this "pattern". In my opinion it has absolutely nothing to do with singleton, its just a kind of factory, which always returns the same object, but doesn't make it singleton... as long as there can be more than one instance of a class it can't be a singleton. Any reason this pattern is top-rated?
public sealed class Singleton
{
private static readonly Singleton _instance = new Singleton();
private Singleton()
{
}
public static Singleton Instance
{
get
{
return _instance;
}
}
}
Static initializers are considered thread-safe.. I don't know but you shouldn't use idioms of singleton at all, if you wrap my code above its not more than 3 lines... and inheriting from a singleton doesn't make any sense either.
I was looking for a better Singleton pattern and liked this one. So ported it to VB.NET, can be useful for others:
Public MustInherit Class Singleton(Of T As {Class, New})
Public Sub New()
End Sub
Private Class SingletonCreator
Shared Sub New()
End Sub
Friend Shared ReadOnly Instance As New T
End Class
Public Shared ReadOnly Property Instance() As T
Get
Return SingletonCreator.Instance
End Get
End Property
End Class
As requested, cross posting from my original answer to another question.
My version uses Reflection, works with non-public constructors in the derived class, is threadsafe (obviously) with lazy instantiation (according to the article I found linked below):
public class SingletonBase<T> where T : class
{
static SingletonBase()
{
}
public static readonly T Instance =
typeof(T).InvokeMember(typeof(T).Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic,
null, null, null) as T;
}
I picked this up a few years ago, not sure how much is mine, but googling on the code might find the original source of the technique if it wasn't me.
This is the oldest source of the code that I can find that was not me posting it.
Try this generic Singleton class implementing the Singleton design pattern in a thread safe and lazy way (thx to wcell).
public abstract class Singleton<T> where T : class
{
/// <summary>
/// Returns the singleton instance.
/// </summary>
public static T Instance
{
get
{
return SingletonAllocator.instance;
}
}
internal static class SingletonAllocator
{
internal static T instance;
static SingletonAllocator()
{
CreateInstance(typeof(T));
}
public static T CreateInstance(Type type)
{
ConstructorInfo[] ctorsPublic = type.GetConstructors(
BindingFlags.Instance | BindingFlags.Public);
if (ctorsPublic.Length > 0)
throw new Exception(
type.FullName + " has one or more public constructors so the property cannot be enforced.");
ConstructorInfo ctorNonPublic = type.GetConstructor(
BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[0], new ParameterModifier[0]);
if (ctorNonPublic == null)
{
throw new Exception(
type.FullName + " doesn't have a private/protected constructor so the property cannot be enforced.");
}
try
{
return instance = (T)ctorNonPublic.Invoke(new object[0]);
}
catch (Exception e)
{
throw new Exception(
"The Singleton couldnt be constructed, check if " + type.FullName + " has a default constructor", e);
}
}
}
}
The Double-Check Locking [Lea99] idiom provided by Microsoft here is amazingly similar to your provided code, unfortunately, this fails the ECMA CLI standard for a puritan view of thread-safe code and may not work correctly in all situations.
In a multi-threaded program, different threads could try to instantiate a class simultaneously. For this reason, a Singleton implementation that relies on an if statement to check whether the instance is null will not be thread-safe. Don't write code like that!
A simple, yet effective means of creating a thread-safe singleton is to use a nested class to instantiate it. The following is an example of a lazy instantiation singleton:
public sealed class Singleton
{
private Singleton() { }
public static Singleton Instance
{
get
{
return SingletonCreator.instance;
}
}
private class SingletonCreator
{
static SingletonCreator() { }
internal static readonly Singleton instance = new Singleton();
}
}
Usage:
Singleton s1 = Singleton.Instance;
Singleton s2 = Singleton.Instance;
if (s1.Equals(s2))
{
Console.WriteLine("Thread-Safe Singleton objects are the same");
}
Generic Solution:
public class Singleton<T>
where T : class, new()
{
private Singleton() { }
public static T Instance
{
get
{
return SingletonCreator.instance;
}
}
private class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T instance = new T();
}
}
Usage:
class TestClass { }
Singleton s1 = Singleton<TestClass>.Instance;
Singleton s2 = Singleton<TestClass>.Instance;
if (s1.Equals(s2))
{
Console.WriteLine("Thread-Safe Generic Singleton objects are the same");
}
Lastly, here is a somewhat releated and usefull suggestion - to help avoid deadlocks that can be caused by using the lock keyword, consider adding the following attribute to help protect code in only public static methods:
using System.Runtime.CompilerServices;
[MethodImpl (MethodImplOptions.Synchronized)]
public static void MySynchronizedMethod()
{
}
References:
C# Cookbook (O'Reilly), Jay Hilyard & Stephen Teilhet
C# 3.0 Design Patterns (O'Reilly), Judith Bishop
CSharp-Online.Net - Singleton design pattern: Thread-safe Singleton
I quite liked your original answer - the only thing missing (according to the link posted by blowdart) is to make the _instance variable volatile, to make sure it has actually been set in the lock.
I actually use blowdarts solution when I have to use a singleton, but I dont have any need to late-instantiate etc.
My contribution for ensuring on demand creation of instance data:
/// <summary>Abstract base class for thread-safe singleton objects</summary>
/// <typeparam name="T">Instance type</typeparam>
public abstract class SingletonOnDemand<T> {
private static object __SYNC = new object();
private static volatile bool _IsInstanceCreated = false;
private static T _Instance = default(T);
/// <summary>Instance data</summary>
public static T Instance {
get {
if (!_IsInstanceCreated)
lock (__SYNC)
if (!_IsInstanceCreated)
_Instance = Activator.CreateInstance<T>();
return _Instance;
}
}
}
pff... again... :)
My contribution for ensuring on demand creation of instance data:
/// <summary>Abstract base class for thread-safe singleton objects</summary>
/// <typeparam name="T">Instance type</typeparam>
public abstract class SingletonOnDemand<T> {
private static object __SYNC = new object();
private static volatile bool _IsInstanceCreated = false;
private static T _Instance = default(T);
/// <summary>Instance data</summary>
public static T Instance {
get {
if (!_IsInstanceCreated)
lock (__SYNC)
if (!_IsInstanceCreated) {
_Instance = Activator.CreateInstance<T>();
_IsInstanceCreated = true;
}
return _Instance;
}
}
}
public static class LazyGlobal<T> where T : new()
{
public static T Instance
{
get { return TType.Instance; }
}
private static class TType
{
public static readonly T Instance = new T();
}
}
// user code:
{
LazyGlobal<Foo>.Instance.Bar();
}
Or:
public delegate T Func<T>();
public static class CustomGlobalActivator<T>
{
public static Func<T> CreateInstance { get; set; }
}
public static class LazyGlobal<T>
{
public static T Instance
{
get { return TType.Instance; }
}
private static class TType
{
public static readonly T Instance = CustomGlobalActivator<T>.CreateInstance();
}
}
{
// setup code:
// CustomGlobalActivator<Foo>.CreateInstance = () => new Foo(instanceOf_SL_or_IoC.DoSomeMagicReturning<FooDependencies>());
CustomGlobalActivator<Foo>.CreateInstance = () => instanceOf_SL_or_IoC.PleaseResolve<Foo>();
// ...
// user code:
LazyGlobal<Foo>.Instance.Bar();
}
Saw one a while ago which uses reflection to access a private (or public) default constructor:
public static class Singleton<T>
{
private static object lockVar = new object();
private static bool made;
private static T _singleton = default(T);
/// <summary>
/// Get The Singleton
/// </summary>
public static T Get
{
get
{
if (!made)
{
lock (lockVar)
{
if (!made)
{
ConstructorInfo cInfo = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[0], null);
if (cInfo != null)
_singleton = (T)cInfo.Invoke(new object[0]);
else
throw new ArgumentException("Type Does Not Have A Default Constructor.");
made = true;
}
}
}
return _singleton;
}
}
}
I submit this to the group. It seems to be thread-safe, generic and follows the pattern. You can inherit from it. This is cobbled together from what others have said.
public class Singleton<T> where T : class
{
class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T Instance =
typeof(T).InvokeMember(typeof(T).Name,
BindingFlags.CreateInstance |
BindingFlags.Instance |
BindingFlags.Public |
BindingFlags.NonPublic,
null, null, null) as T;
}
public static T Instance
{
get { return SingletonCreator.Instance; }
}
}
Intended implementation:
public class Foo: Singleton<Foo>
{
private Foo() { }
}
Then:
Foo.Instance.SomeMethod();
As in wikipedia:
the singleton pattern is a design pattern that restricts the
instantiation of a class to one object
I beleave that there is no guaranteed way to do it using generics, if you have restricted the instantiation of the singleton itself, how to restrict the instantiation of the main class, I think it is not possible to do that, and implementing this simple pattern is not that hard, take this way using the static constructor and private set:
public class MyClass
{
private MyClass()
{
}
static MyClass()
{
Instance = new MyClass();
}
public static MyClass Instance { get; private set; }
}
OR:
public class MyClass
{
private MyClass()
{
}
static MyClass()
{
Instance = new MyClass();
}
private static MyClass instance;
public static MyClass Instance
{
get
{
return instance;
}
private set
{
instance = value;
}
}
}
This works for me:
public static class Singleton<T>
{
private static readonly object Sync = new object();
public static T GetSingleton(ref T singletonMember, Func<T> initializer)
{
if (singletonMember == null)
{
lock (Sync)
{
if (singletonMember == null)
singletonMember = initializer();
}
}
return singletonMember;
}
}
Usage:
private static MyType _current;
public static MyType Current = Singleton<MyType>.GetSingleton(ref _current, () => new MyType());
Consume the singleton:
MyType.Current. ...
No Matter which exmaple you choose, always check for concurrency using Parallel.For!
( loop in which iterations may run in parallel)
put in Singleton C'tor :
private Singleton ()
{
Console.WriteLine("usage of the Singleton for the first time");
}
put in Main :
Parallel.For(0, 10,
index => {
Thread tt = new Thread(new ThreadStart(Singleton.Instance.SomePrintMethod));
tt.Start();
});
In many solutions today, people use service lifetime of singleton with dependency injection, as .NET offers this out of the box. If you still want to create a generic singleton pattern in your code where you might also consider initializing the type T to a initialized singleton object, 'settable once' and thread safe, here is a possible way to do it.
public sealed class Singleton<T> where T : class, new()
{
private static Lazy<T> InstanceProxy
{
get
{
if (_instanceObj?.IsValueCreated != true)
{
_instanceObj = new Lazy<T>(() => new T());
}
return _instanceObj;
}
}
private static Lazy<T>? _instanceObj;
public static T Instance { get { return InstanceProxy.Value; } }
public static void Init(Lazy<T> instance)
{
if (_instanceObj?.IsValueCreated == true)
{
throw new ArgumentException($"A Singleton for the type <T> is already set");
}
_instanceObj = instance ?? throw new ArgumentNullException(nameof(instance));
}
private Singleton()
{
}
}
The class is sealed and with a private constructor, it accepts types which are classes and must offer a public parameterless constructor 'new'. It uses the Lazy to achieve built in thread safety. You can init also the type T Singleton object for convenience. It is only allowed if a Singleton is not first set. Obviously, you should only init a Singleton of type T early on in your program, such as when the application or service / API starts up. The code will throw an ArgumentException if the Init method is called twice or more times for the type T.
You can use it like this :
Some model class :
public class Aeroplane
{
public string? Model { get; set; }
public string? Manufacturer { get; set; }
public int YearBuilt { get; set; }
public int PassengerCount { get; set; }
}
Usage sample :
var aeroplane = new Aeroplane
{
Manufacturer = "Boeing",
Model = "747",
PassengerCount = 350,
YearBuilt = 2005
};
var aeroPlane3 = Singleton<Aeroplane>.Instance;
var aeroPlane4 = Singleton<Aeroplane>.Instance;
Console.WriteLine($"Aeroplane3 and aeroplane4 is same object? {Object.ReferenceEquals(aeroPlane3, aeroPlane4)}");
Outputs 'true'.
Trying to re-init type T Singleton to another object fails :
var aeroplane2 = new Aeroplane
{
Manufacturer = "Sopwith Aviation Company",
Model = "Sophwith Camel",
PassengerCount = 1,
YearBuilt = 1917
};
Singleton<Aeroplane>.Init(new Lazy<Aeroplane>(aeroplane2));
You can of course just access the Singleton with initing it - it will call the default public constructor. Possible you could have a way of setting a custom constructor here instead of passing an object as a sort of 'factory pattern'.
var aeroplaneDefaultInstantiated = Singleton<Aeroplane>.Instance;
Default instantiation - calls the parameterless public constructor of type T.
You don't need all that, C# already has a good singleton pattern built-in.
static class Foo
If you need anything more interesting than that, chances are your new singleton is going to be just different enough that your generic pattern is going to be useless.
EDIT: By "anything more interesting" I'm including inheritance. If you can inherit from a singleton, it isn't a singleton any more.