Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通用单例<;T>;_C#_Oop_Design Patterns_Singleton - Fatal编程技术网

C# 通用单例<;T>;

C# 通用单例<;T>;,c#,oop,design-patterns,singleton,C#,Oop,Design Patterns,Singleton,我有一个问题,这是制作通用单例的正确方法吗 public class Singleton<T> where T : class, new() { private static T instance = null; private Singleton() { } public static T Instancia { get {

我有一个问题,这是制作通用单例的正确方法吗

 public class Singleton<T> where T : class, new()
    {
        private static T instance = null;

        private Singleton() { }

        public static T Instancia
        {
            get 
            {
                if (instance == null)
                    instance = new T();
                return instance;
            }
        }
    }
公共类单例,其中T:class,new()
{
私有静态T实例=null;
私有单例(){}
公共静态T实例
{
得到
{
if(实例==null)
实例=新的T();
返回实例;
}
}
}
编辑:

在检查一些PDF时,我发现一个通用的单例是以这种方式制作的,这种方式正确吗

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; }
    }
}
公共类单例,其中T:class,new()
{
Singleton(){}
类单音创建者
{
静态SingletonCreator(){}
//使用私有构造函数实例化的私有对象
内部静态只读T实例=新T();
}
公共静态T唯一实例
{
获取{return SingletonCreator.instance;}
}
}

通用单例工厂的问题在于,由于它是通用的,因此您无法控制实例化的“单例”类型,因此您永远无法保证您创建的实例将是应用程序中唯一的实例


如果用户可以将类型作为泛型类型参数提供给,则还可以创建该类型的实例。换句话说,<强>您不能创建一个通用的单工厂——它破坏了模式本身。< /强>

对于一个将被重用的通用代码段,您应该在创建单实例的时候考虑线程安全性。p>
实际上,
(instance==null)
可以在单独的线程上计算为true。

这是我使用.NET 4的观点

public class Singleton<T> where T : class, new()
    {
        private Singleton (){}

        private static readonly Lazy<T> instance = new Lazy<T>(()=> new T());

        public static T Instance { get { return instance.Value; } } 
    }
公共类单例,其中T:class,new()
{
私有单例(){}
私有静态只读惰性实例=newlazy(()=>newt());
公共静态T实例{get{return Instance.Value;}}
}
使用模式:

var journalSingleton = Singleton<JournalClass>.Instance;
var journalSingleton=Singleton.Instance;

以下是我使用非公共构造函数的实现。现在唯一的问题是没有办法对C#泛型进行自定义约束,因此我必须为具有公共默认构造函数的派生类抛出运行时异常,而不是编译时错误

using System;
using System.Reflection;
using System.Threading;

/// <summary>
/// A generic abstract implementation of the Singleton design pattern (http://en.wikipedia.org/wiki/Singleton_pattern).
/// 
/// Derived type must contain a non-public default constructor to satisfy the rules of the Singleton Pattern.
/// If no matching constructor is found, an exception will be thrown at run-time. I am working on a StyleCop
/// constraint that will throw a compile-time error in the future.
/// 
/// Example Usage (C#):
/// 
///     class MySingleton : Singleton&lt;MySingleton&gt;
///     {
///         private const string HelloWorldMessage = "Hello World - from MySingleton";
///     
///         public string HelloWorld { get; private set; }
///
///         // Note: *** Private Constructor ***
///         private MySingleton()
///         {
///             // Set default message here.
///             HelloWorld = HelloWorldMessage;
///         }
///     }
/// 
///     class Program
///     {
///         static void Main()
///         {
///             var mySingleton = MySingleton.Instance;
///             Console.WriteLine(mySingleton.HelloWorld);
///             Console.ReadKey();
///         }
///     }
/// </summary>
/// <typeparam name="T">Type of derived Singleton object (i.e. class MySingletone: Singleton&lt;MySingleton&gt;).</typeparam>
public abstract class Singleton<T> where T : class
{
    /// <summary>
    /// "_instance" is the meat of the Singleton<T> base-class, as it both holds the instance
    /// pointer and the reflection based factory class used by Lazy&lt;T&gt; for instantiation.
    /// 
    /// Lazy&lt;T&gt;.ctor(Func&lt;T&gt; valueFactory,LazyThreadSafetyMode mode), valueFactory:
    /// 
    ///     Due to the fact Lazy&lt;T&gt; cannot access a singleton's (non-public) default constructor and
    ///     there is no "non-public default constructor required" constraint available for C# 
    ///     generic types, Lazy&lt;T&gt;'s valueFactory Lambda uses reflection to create the instance.
    ///
    /// Lazy&lt;T&gt;.ctor(Func&lt;T&gt; valueFactory,LazyThreadSafetyMode mode), mode:
    /// 
    ///     Explanation of selected mode (ExecutionAndPublication) is from MSDN.
    ///     
    ///     Locks are used to ensure that only a single thread can initialize a Lazy&lt;T&gt; instance 
    ///     in a thread-safe manner. If the initialization method (or the default constructor, if 
    ///     there is no initialization method) uses locks internally, deadlocks can occur. If you 
    ///     use a Lazy&lt;T&gt; constructor that specifies an initialization method (valueFactory parameter),
    ///     and if that initialization method throws an exception (or fails to handle an exception) the 
    ///     first time you call the Lazy&lt;T&gt;.Value property, then the exception is cached and thrown
    ///     again on subsequent calls to the Lazy&lt;T&gt;.Value property. If you use a Lazy&lt;T&gt; 
    ///     constructor that does not specify an initialization method, exceptions that are thrown by
    ///     the default constructor for T are not cached. In that case, a subsequent call to the 
    ///     Lazy&lt;T&gt;.Value property might successfully initialize the Lazy&lt;T&gt; instance. If the
    ///     initialization method recursively accesses the Value property of the Lazy&lt;T&gt; instance,
    ///     an InvalidOperationException is thrown.
    /// 
    /// </summary>
    private static readonly Lazy<T> _instance = new Lazy<T>(() =>
                                                                {
                                                                    // Get non-public constructors for T.
                                                                    var ctors = typeof (T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);

                                                                    // If we can't find the right type of construcor, throw an exception.
                                                                    if (!Array.Exists(ctors, (ci) => ci.GetParameters().Length == 0))
                                                                    {
                                                                        throw new ConstructorNotFoundException("Non-public ctor() note found.");
                                                                    }

                                                                    // Get reference to default non-public constructor.
                                                                    var ctor = Array.Find(ctors, (ci) => ci.GetParameters().Length == 0);

                                                                    // Invoke constructor and return resulting object.
                                                                    return ctor.Invoke(new object[] {}) as T;
                                                                }, LazyThreadSafetyMode.ExecutionAndPublication);

    /// <summary>
    /// Singleton instance access property.
    /// </summary>
    public static T Instance
    {
        get { return _instance.Value; }
    }
}

/// <summary>
/// Exception thrown by Singleton&lt;T&gt; when derived type does not contain a non-public default constructor.
/// </summary>
public class ConstructorNotFoundException : Exception
{
    private const string ConstructorNotFoundMessage = "Singleton<T> derived types require a non-public default constructor.";
    public ConstructorNotFoundException() : base(ConstructorNotFoundMessage) { }
    public ConstructorNotFoundException(string auxMessage) : base(String.Format("{0} - {1}", ConstructorNotFoundMessage, auxMessage)) { }
    public ConstructorNotFoundException(string auxMessage, Exception inner) : base(String.Format("{0} - {1}", ConstructorNotFoundMessage, auxMessage), inner) { }
}
使用系统;
运用系统反思;
使用系统线程;
/// 
///Singleton设计模式的通用抽象实现(http://en.wikipedia.org/wiki/Singleton_pattern).
/// 
///派生类型必须包含非公共的默认构造函数,以满足单例模式的规则。
///如果找不到匹配的构造函数,将在运行时引发异常。我在做一个时尚警察
///约束,该约束将在将来引发编译时错误。
/// 
///用法示例(C#):
/// 
///类MySingleton:SingletonMySingleton
///     {
///private const string HelloWorldMessage=“Hello World-来自MySingleton”;
///     
///公共字符串HelloWorld{get;private set;}
///
/////注意:**私有构造函数***
///二等兵迈辛格尔顿()
///         {
/////在此处设置默认消息。
///HelloWorld=HelloWorldMessage;
///         }
///     }
/// 
///班级计划
///     {
///静态void Main()
///         {
///var mySingleton=mySingleton.Instance;
///Console.WriteLine(mySingleton.HelloWorld);
///Console.ReadKey();
///         }
///     }
/// 
///派生的单例对象的类型(即类MySingletone:SingletonMySingleton)。
公共抽象类单例,其中T:class
{
/// 
///“_instance”是Singleton基类的核心,因为它都包含实例
///指针和LazyT用于实例化的基于反射的工厂类。
/// 
///LazyT.ctor(FuncT valueFactory,LazyThreadSafetyMode模式),valueFactory:
/// 
///由于LazyT无法访问singleton的(非公共)默认构造函数和
///C#没有“非公共默认构造函数必需”约束
///在泛型类型中,LazyT的valueFactory Lambda使用反射创建实例。
///
///LazyT.ctor(函数值工厂,LazyThreadSafetyMode模式),模式:
/// 
///所选模式(ExecutionAndPublication)的说明来自MSDN。
///     
///锁用于确保只有一个线程可以初始化LazyT实例
///以线程安全的方式。如果初始化方法(或默认构造函数,如果
///没有初始化方法)在内部使用锁,可能会发生死锁
///使用LazyT构造函数指定初始化方法(valueFactory参数),
///如果该初始化方法引发异常(或无法处理异常),则
///第一次调用LazyT.Value属性时,将缓存并引发异常
///在后续调用LazyT.Value属性时,如果使用LazyT
///未指定初始化方法的构造函数,以及
///未缓存T的默认构造函数
///Value属性可能会成功初始化LazyT实例
///初始化方法递归访问LazyT实例的Value属性,
///引发InvalidOperationException。
/// 
/// 
私有静态只读惰性_实例=新惰性(()=>
{
//为T获取非公共构造函数。
var ctors=typeof(T).getconstructor(BindingFlags.Instance | BindingFlags.NonPublic);
public abstract class BaseLazySingleton<T> where T : class
    {
        private static readonly Lazy<T> LazyInstance =
            new Lazy<T>(CreateInstanceOfT, LazyThreadSafetyMode.ExecutionAndPublication);

        #region Properties
        public static T Instance
        {
            get { return LazyInstance.Value; }
        }
        #endregion

        #region Methods
        private static T CreateInstanceOfT()
        {
            return Activator.CreateInstance(typeof(T), true) as T;
        }

        protected BaseLazySingleton()
        {
        }

        #endregion
    }
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;
    }
}
private static MyType _current;
public static MyType Current = Singleton<MyType>.GetSingleton(ref _current, () => new MyType());
MyType.Current. ...
public abstract class Singleton<T> where T : Singleton<T> {
    private const string ErrorMessage = " must have a parameterless constructor and all constructors have to be NonPublic.";
    private static T instance = null;
    public static T Instance => instance ?? (instance = Create());

    protected Singleton() {
        //check for public constructors
        var pconstr = typeof(T).GetConstructors(BindingFlags.Public | BindingFlags.Instance);
        //tell programmer to fix his stuff
        if (pconstr.Any())
            throw new Exception(typeof(T) + ErrorMessage);
    }

    private static T Create() {
        try {
            //get nonpublic constructors
            var constructors = typeof(T).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
            //make sure there is but 1 and use that
            return (T)constructors.Single().Invoke(null);
        }
        catch {
            //tell programmer to fix his stuff
            throw new Exception(typeof(T)+ErrorMessage);
        }
    }
}
using System;
using System.Diagnostics;

namespace Singleton
{
    class Program
    {
        static void Main(string[] args)
        {
            Something.Instance.SayHello();
        }
    }

    /// <summary>
    /// Generic singleton pattern implementation
    /// </summary>
    public class SingletonImplementation<Implementation, ImplementationInterface>
           where Implementation : class, ImplementationInterface, new()
    {
        private SingletonImplementation() { }

        private static Implementation instance = null;
        public static ImplementationInterface Instance
        {
            get
            {
                // here you can add your singleton stuff, which you don't like to write all the time

                if ( instance == null )
                {
                    instance = new Implementation();
                }

                return instance;
            }
        }
    }

    /// <summary>
    /// Interface for the concrete singleton
    /// </summary>
    public interface ISomething
    {
        void SayHello();
    }

    /// <summary>
    /// Singleton "held" or "wrapper" which provides the instance of the concrete singleton
    /// </summary>
    public static class Something
    {
        // No need to define the ctor private, coz you can't do anything wrong or useful with an instance of Something
        // private Implementation();

        /// <summary>
        /// Like common: the static instance to access the concrete singleton
        /// </summary>
        public static ISomething Instance => SingletonImplementation<ImplementationOfSomething, ISomething>.Instance;

        /// <summary>
        /// Concrete singleton implementation
        /// </summary>
        private class ImplementationOfSomething : ISomething
        {
            // No need to define the ctor private, coz the class is private.
            // private Implementation();

            public void SayHello()
            {
                Debug.WriteLine("Hello world.");
            }
        }
    }
}
template < class T> 
class singleton
{
private:
    static T* _instance;

public:
    static T* CreateInstance()
    {
        if (_instance == 0)  _instance = new T;
        return _instance;


    }
    static void Release()
    {

        if (_instance)
        {
            delete _instance;
            _instance = 0;

        }
    }
};

template<class T> T* singleton<T>::_instance = 0;