英文:
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<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!
答案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<Publisher1, EventHandler> {
{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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论