集中事件声明在C#中

huangapple go评论65阅读模式
英文:

Centralize event declaration in C#

问题

I have a piece of code that follows the Observer pattern. Each publisher creates events and invokes them accordingly for subscribers to consume. I thought of creating an 'EventRegistry' where all events are registered (as dictionaries <Enum, event>). That way both subscribers and publishers have a central place to know what events are available, instead of having to import each file where the event was created.

I tried the code below but it doesn't work. I implemented the registry as a singleton (following this implementation), so events are created only once. I'm not too familiar with C#, so I'm not sure what's wrong. The error I get:

A field initializer cannot reference the non-static field, method, or property 'EventRegistry.Event1' [Assembly-CSharp]

The code:

using System;
using System.Collections.Generic;
using MyNamespace;

namespace MyNamespace
{
    class EventRegistry
    {
        private EventRegistry() { }

        private static EventRegistry _instance;

        private static readonly object _lock = new object();

        public static EventRegistry GetInstance()
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new EventRegistry();
                    }
                }
            }
            return _instance;
        }

        private enum Publisher1 {
            Event1,
        }
        private event EventHandler Event1;

        public Dictionary<Publisher1, EventHandler> Publisher1Events {get;} = new Dictionary<Publisher1, EventHandler> {
            {Publisher1.Event1, Event1}
        };
    }
}

I'm aware that Singletons are evil. I think this is a good use case for it though, but if there's a better way feel free to suggest otherwise!

英文:

I have a piece of code that follows the Observer pattern. Each publisher creates events and invokes them accordingly for subscribers to consume. I thought of creating an EventRegistry where all events are registered (as dictionaries <Enum, event>). That way both subscribers and publishers have a central place to know what events are available, instead of having to import each file where the event was created.

I tried the code below but it doesn't work. I implemented the registry as a singleton (following this implementation), so events are created only once. I'm not too familiar with C#, so I'm not sure what's wrong. The error I get:

> A field initializer cannot reference the non-static field, method, or
> property 'EventRegistry.Event1' [Assembly-CSharp]

The code:

using System;
using System.Collections.Generic;
using MyNamespace;

namespace MyNamespace
{
    class EventRegistry
    {
        private EventRegistry() { }

        private static EventRegistry _instance;

        private static readonly object _lock = new object();

        public static EventRegistry GetInstance()
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                    {
                        _instance = new EventRegistry();
                    }
                }
            }
            return _instance;
        }

        private enum Publisher1 {
            Event1,
        }
        private event EventHandler Event1;

        public Dictionary&lt;Publisher1, EventHandler&gt; Publisher1Events {get;} = new Dictionary&lt;Publisher1, EventHandler&gt; {
            {Publisher1.Event1, Event1}
        };
    }
}

I'm aware that Singletons are evil. I think this is a good use case for it though, but if there's a better way feel free to suggest otherwise!

答案1

得分: 1

你需要在你的私有构造函数中初始化 Publisher1Events,如下所示:

private EventRegistry()
{
    Publisher1Events = new Dictionary<Publisher1, EventHandler> {
        {Publisher1.Event1, Event1}
    };
}

而且你需要将 Publisher1 枚举声明为公共的。

之所以需要在构造函数中初始化,是因为字段初始化器要求使用常量或静态值。

英文:

You have to initialize Publisher1Events in your private constructor, like:

private EventRegistry()
{
	Publisher1Events = new Dictionary&lt;Publisher1, EventHandler&gt; {
		{Publisher1.Event1, Event1}
	};
}

And you have to make the Publisher1 enum public.

The reason you have to initialize in the constructor is because field initializers require constant or static values.

huangapple
  • 本文由 发表于 2023年7月3日 10:53:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76601602.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定