集中事件声明在C#中

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

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:

  1. using System;
  2. using System.Collections.Generic;
  3. using MyNamespace;
  4. namespace MyNamespace
  5. {
  6. class EventRegistry
  7. {
  8. private EventRegistry() { }
  9. private static EventRegistry _instance;
  10. private static readonly object _lock = new object();
  11. public static EventRegistry GetInstance()
  12. {
  13. if (_instance == null)
  14. {
  15. lock (_lock)
  16. {
  17. if (_instance == null)
  18. {
  19. _instance = new EventRegistry();
  20. }
  21. }
  22. }
  23. return _instance;
  24. }
  25. private enum Publisher1 {
  26. Event1,
  27. }
  28. private event EventHandler Event1;
  29. public Dictionary<Publisher1, EventHandler> Publisher1Events {get;} = new Dictionary<Publisher1, EventHandler> {
  30. {Publisher1.Event1, Event1}
  31. };
  32. }
  33. }

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:

  1. using System;
  2. using System.Collections.Generic;
  3. using MyNamespace;
  4. namespace MyNamespace
  5. {
  6. class EventRegistry
  7. {
  8. private EventRegistry() { }
  9. private static EventRegistry _instance;
  10. private static readonly object _lock = new object();
  11. public static EventRegistry GetInstance()
  12. {
  13. if (_instance == null)
  14. {
  15. lock (_lock)
  16. {
  17. if (_instance == null)
  18. {
  19. _instance = new EventRegistry();
  20. }
  21. }
  22. }
  23. return _instance;
  24. }
  25. private enum Publisher1 {
  26. Event1,
  27. }
  28. private event EventHandler Event1;
  29. public Dictionary&lt;Publisher1, EventHandler&gt; Publisher1Events {get;} = new Dictionary&lt;Publisher1, EventHandler&gt; {
  30. {Publisher1.Event1, Event1}
  31. };
  32. }
  33. }

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,如下所示:

  1. private EventRegistry()
  2. {
  3. Publisher1Events = new Dictionary<Publisher1, EventHandler> {
  4. {Publisher1.Event1, Event1}
  5. };
  6. }

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

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

英文:

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

  1. private EventRegistry()
  2. {
  3. Publisher1Events = new Dictionary&lt;Publisher1, EventHandler&gt; {
  4. {Publisher1.Event1, Event1}
  5. };
  6. }

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:

确定