静态类中的C#单例模式?

时间:2022-09-02 08:50:38

My event dispatcher class loosely couples instances of other classes by implementing sort of signals-slots design pattern.

我的事件调度程序类通过实现一些信号槽设计模式松散地耦合其他类的实例。

Only one unique event dispatcher is supposed to exist in an application. Since my Dispatcher class – which does all the work – inherits from Dictionary<TKey, TValue>, it cannot be declared static.

应用程序中只应存在一个唯一的事件调度程序。由于我的Dispatcher类(完成所有工作)继承自Dictionary ,因此不能将其声明为静态。 ,tvalue>

To overcome this constraint, I implemented a main static wrapper class EVD with a private property evd which provides the Dispatcher singleton, along with the public static methods Subscribe, UnSubscribe, and Dispatch, which wrap the singleton's corresponding methods:

为了克服这个限制,我实现了一个带有私有属性evd的主静态包装类EVD,它提供了Dispatcher单例,以及包含单例相应方法的公共静态方法Subscribe,UnSubscribe和Dispatch:

namespace EventDispatcher
{
    public static class EVD
    {
        static Dispatcher evd { get { return Singleton<Dispatcher>.Instance; } }

        public static void Subscribe(string name, EvtHandler handler)
        {
            evd.Subscribe(name, handler);
        }
        public static void UnSubscribe(string name, EvtHandler handler = null)
        {
            evd.UnSubscribe(name, handler);
        }
        public static void Dispatch(string name, object sender, EvtArgs e = null)
        {
            evd.Dispatch(name, sender, e);
        }
    }

    class Dispatcher : Dictionary<string, Event> { /* main event dispatcher */ }

    static class Singleton<T> where T : /* generic singleton creation */
}

So here is my question:

所以这是我的问题:

Does it really make sense to create a singleton instance in a static class? AFAIK a static class is unique anyway. So maybe it would be best practice not to create the singleton and declare the evd property just like so:

在静态类中创建单例实例真的有意义吗? AFAIK静态类无论如何都是独一无二的。所以也许最好的做法是不创建单例并声明evd属性就像这样:

static Dispatcher evd = new Dispatcher();

What about lazy intantiation and thread safety in that case? At least the generic singleton class uses Lazy<T> and is said to be thread safe.

在这种情况下,懒惰的实例化和线程安全性如何?至少通用单例类使用Lazy 并且被认为是线程安全的。

Or should I better declare the property like so:

或者我应该更好地声明属性如下:

static Dispatcher _evd;
static Dispatcher evd 
{ 
    get { return _evd ?? (_evd = new Dispatcher()); }
}

I'm afraid I don't completely understand all that lazy instatantiation and thread safety stuff...

我担心我不完全理解所有懒惰的instatantiation和线程安全的东西......

Thanks for any help, Don P

感谢任何帮助,Don P.

1 个解决方案

#1


No, since you can't create instances of a static class there will only be one copy of the field, so there is no need to use the Singleton pattern.

不,因为您无法创建静态类的实例,所以只有该字段的一个副本,因此不需要使用Singleton模式。

Place the construction in the static constructor, which is guaranteed to be called only once, and is thereby automatically thread-safe: https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

将构造放置在静态构造函数中,该构造函数保证只调用一次,从而自动进行线程安全:https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

Extra reference: it look corresponding to the "static field" inside "Employee Type Object" here: http://www.rvenables.com/linkjackandsufferaccidentaldroptable/clr_via_csharp_f4.9.png

额外参考:它看起来对应于“员工类型对象”中的“静态字段”:http://www.rvenables.com/linkjackandsufferaccidentaldroptable/clr_via_csharp_f4.9.png

#1


No, since you can't create instances of a static class there will only be one copy of the field, so there is no need to use the Singleton pattern.

不,因为您无法创建静态类的实例,所以只有该字段的一个副本,因此不需要使用Singleton模式。

Place the construction in the static constructor, which is guaranteed to be called only once, and is thereby automatically thread-safe: https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

将构造放置在静态构造函数中,该构造函数保证只调用一次,从而自动进行线程安全:https://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

Extra reference: it look corresponding to the "static field" inside "Employee Type Object" here: http://www.rvenables.com/linkjackandsufferaccidentaldroptable/clr_via_csharp_f4.9.png

额外参考:它看起来对应于“员工类型对象”中的“静态字段”:http://www.rvenables.com/linkjackandsufferaccidentaldroptable/clr_via_csharp_f4.9.png