问题描述
我有以下C#Singleton模式,有什么方法可以改进它吗?
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() { } }
首选用法示例:
class Foo : Singleton<Foo> { }
相关:
.net的明显Singleton实现?
推荐答案
根据在C#中实现Singleton模式实际上被认为是不良代码,因为它在根据ECMA CLI标准检查时似乎破裂了.
还要注意:每次使用新型t实例化对象时,它都会成为另一个实例;它不会反映在您的原始Singleton中.
其他推荐答案
此代码不会编译,您需要在T.
上进行"类"约束.另外,此代码需要目标类上的公共构造函数,这对Singleton不利,因为您无法在获得(单个)实例(单个)实例属性(或字段)中获得的编译时间(单个)实例.如果您没有任何其他静态成员,则可以使用此操作:
class Foo { public static readonly Instance = new Foo(); private Foo() {} static Foo() {} }
它是线程安全的(由CLR保证)和Lazy(创建实例是使用首先访问类型的).有关Foreffieldinit的更多讨论以及为什么我们在此处需要静态构造函数,请参见 https://csharpindepth.com/csharpindepth.com/article.com/article
如果您想在类型上拥有其他公共静态成员,但是仅在访问实例上创建对象,则可以创建嵌套类型,例如 https://csharpindepth.com/articles/singleton
其他推荐答案
由朱迪思·毕晓普(Judith Bishop)提供, http://patterns.cs.up.ac.ac.ac.ac.za/
此单例模式实现可确保懒惰的初始化.
// 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; } } }
问题描述
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; } } }