fork download
  1.  
  2. //некое событие
  3. public interface IEvent{}
  4.  
  5. //обработчик события
  6. public interface IEventHandler<T> where T : class, IEvent
  7. {
  8. public void HandleEvent(T @event);
  9. }
  10.  
  11. public class EventDispatcher{
  12. private Dictionary<Type, List<WeakReference>> _handlers = new();
  13. private object _locker = new();
  14. public void Subscribe<T>(IEventHandler<T> handler) where T : class, IEvent
  15. {
  16. var type = typeof(T);
  17. lock(_locker){
  18. if(!_handlers.TryGetValue(type, out var handlers)){
  19. handlers = new();
  20. _handlers[type] = handlers;
  21. }
  22. var refs = handlers.Find(x=>x.Target == handler);
  23. if(refs is not null){
  24. throw new InvalidOperationException();
  25. }
  26. refs = new(handler);
  27. handlers.Add(refs);
  28. }
  29. }
  30.  
  31. public void Unsubscribe<T>(IEventHandler<T> handler) where T : class, IEvent
  32. {
  33. var type = typeof(T);
  34. lock(_locker){
  35. if(!_handlers.ContainsKey(type)){
  36. throw new InvalidOperationException();
  37. }
  38. var handlers = _handlers[type];
  39. var refs = handlers.Find(x=>x.Target == handlers);
  40. if(refs is null){
  41. throw new InvalidOperationException();
  42. }
  43. handlers.Remove(refs);
  44. }
  45. }
  46.  
  47. public void Handle<T>(T @event) where T : class, IEvent
  48. {
  49. var type = typeof(T);
  50. //не даем подписываться пока идет обработка)))
  51. lock(_locker){
  52. if(!_handlers.ContainsKey(type)){
  53. return;
  54. }
  55. var handlers = _handlers[type];
  56. List<WeakReference> toRemove = new();
  57. foreach(var handlerRef in handlers){
  58. if(!handlerRef.IsAlive){
  59. toRemove.Add(handlerRef);
  60. continue;
  61. }
  62. if(handlerRef.Target is null){
  63. toRemove.Add(handlerRef);
  64. continue;
  65. }
  66. var handler = handlerRef.Target as IEventHandler<T>;
  67. if(handler is null){
  68. toRemove.Add(handlerRef);
  69. continue;
  70. }
  71. handler.HandleEvent(@event);
  72. }
  73. foreach(var i in toRemove){
  74. handlers.Remove(i);
  75. }
  76. }
  77. }
  78. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cs(8,17): error CS0106: The modifier `public' is not valid for this item
prog.cs(12,66): error CS1525: Unexpected symbol `)', expecting `(' or `type'
prog.cs(13,33): error CS1525: Unexpected symbol `)', expecting `(' or `type'
prog.cs(19,31): error CS1525: Unexpected symbol `)', expecting `(' or `type'
prog.cs(23,27): error CS1525: Unexpected symbol `null'
prog.cs(26,23): error CS8124: Tuple must contain at least two elements
prog.cs(26,31): error CS1525: Unexpected symbol `;', expecting `(', `[', or `{'
prog.cs(40,21): error CS1644: Feature `pattern matching' cannot be used because it is not part of the C# 7.0 language specification
prog.cs(56,47): error CS1525: Unexpected symbol `)', expecting `(' or `type'
prog.cs(62,38): error CS1644: Feature `pattern matching' cannot be used because it is not part of the C# 7.0 language specification
prog.cs(67,28): error CS1644: Feature `pattern matching' cannot be used because it is not part of the C# 7.0 language specification
Compilation failed: 11 error(s), 0 warnings
stdout
Standard output is empty