Sam*_*ron 31 c# design-patterns
我有以下C#单例模式,有什么方法可以改进它吗?
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()
{ }
}
Run Code Online (Sandbox Code Playgroud)
首选用法示例:
class Foo : Singleton<Foo>
{
}
Run Code Online (Sandbox Code Playgroud)
相关:
Jon*_*jap 18
根据Jon Skeet在C#中实现单例模式的过程,您发布的代码实际上被认为是错误的代码,因为在根据ECMA CLI标准进行检查时它看起来很糟糕.
还要注意:每次使用新类型的T实例化对象时,它都会成为另一个实例; 它没有反映在原来的单身人士身上.
由Judith Bishop提供,http://patterns.cs.up.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; }
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码不会编译,你需要在T上有"类"约束.
此外,此代码需要目标类上的公共构造函数,这对单例不利,因为您无法在编译时控制仅通过实例属性(或字段)获取(单个)实例.如果你没有除Instance之外的任何其他静态成员,你可以这样做:
class Foo
{
public static readonly Instance = new Foo();
private Foo() {}
static Foo() {}
}
Run Code Online (Sandbox Code Playgroud)
它是线程安全的(由CLR保证)和延迟(实例是在首次访问类型时创建的).有关BeforeFieldInit的更多讨论以及我们在此需要静态构造函数的原因,请参阅http://www.yoda.arachsys.com/csharp/beforefieldinit.html.
如果要在类型上拥有其他公共静态成员,但仅在访问Instance时创建对象,则可以创建嵌套类型,如http://www.yoda.arachsys.com/csharp/singleton.html
这是我使用.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; } }
}
Run Code Online (Sandbox Code Playgroud)