在C#中,什么是好的线程安全的单子通用模板模式?[英] What's a good threadsafe singleton generic template pattern in C#

本文是小编为大家收集整理的关于在C#中,什么是好的线程安全的单子通用模板模式?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有以下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; }
    }
}

本文地址:https://www.itbaoku.cn/post/627533.html

问题描述

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; }
    }
}