C#中一个好的线程安全单例通用模板模式是什么

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)

相关:

.NET的一个明显的单例实现?

Jon*_*jap 18

根据Jon Skeet在C#实现单例模式的过程,您发布的代码实际上被认为是错误的代码,因为在根据ECMA CLI标准进行检查时它看起来很糟糕.

还要注意:每次使用新类型的T实例化对象时,它都会成为另一个实例; 它没有反映在原来的单身人士身上.


Dar*_*der 9

由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)

  • 对不起,我不再觉得这是正确的,问题是你最终有一个既新手又可以通过单身人士访问的类型...... (2认同)
  • T必须有_public_`new()` (2认同)

Ily*_*kov 9

这段代码不会编译,你需要在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


Ale*_*ndr 6

这是我使用.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)