[英]How to represent any event and any function in C#?
我有开发一个 class 以安全的方式管理事件取消订阅的想法,因此我不必在时间到来时手动写入-=
到该系统的每个事件订阅(在这个系统中有订阅的事件组并一起退订)。
我想创建一个 class 来管理Dictionary
,其中键是事件(任何可能的事件),值是方法(任何可能的方法)。 这样,我将有一种方法可以将 function 订阅到一个事件中,并且它会在Dictionary
中注册该对的同时做到这一点; 以及取消订阅使用此 class 添加的所有事件的另一种方法(它只会迭代字典并取消订阅所有事件)。
问题是:我找不到任何事件的通用类型,我可以将其用作字典键的通用参数,而且我不知道如何在 C# 中表示任何 function 以设置为字典的值。 在 C/C++ 中,我可以将它们都视为 void 指针,因为我需要的只是 function 本身的指针。
使用 C# 甚至可以做到吗? 是否有更好的方法/策略来实现这一目标?
您必须想出一种为事件生成密钥的方法,因为您不能将普通event
用作字典键。 一种方法是将事件的声明 class 名称与事件名称连接起来。
然后,您可以使用字典,将其用作键,并将List<Action>
作为值。 在这里, Action
将是一个委托,您可以调用它来取消订阅。
您可以将该字典包装在 class 中,以提供Subscribe()
和Unsubscribe()
方法,如下所示:
using System;
using System.Collections.Generic;
namespace ConsoleApp2
{
class Program
{
static void Main()
{
string eventKey = test.GetType().FullName + '.' + nameof(test.MyEvent);
subs.Subscribe(eventKey, () => test.MyEvent += handler, () => test.MyEvent -= handler);
subs.Subscribe(eventKey, () => test.MyEvent += handler, () => test.MyEvent -= handler);
test.RaiseEvent(); // Two handlers called.
subs.Unsubscribe(eventKey);
test.RaiseEvent(); // No handlers called (both were unsubscribed).
}
static void handler(object sender, EventArgs args)
{
Console.WriteLine("Handling event.");
}
static readonly Test test = new Test();
static readonly EventSubscriptions subs = new EventSubscriptions();
}
public class EventSubscriptions
{
public void Subscribe(string key, Action subscribe, Action unsubscribe)
{
subscriptions.TryGetValue(key, out var subs);
if (subs == null)
{
subs = new List<Action>();
subscriptions.Add(key, subs);
}
subscribe();
subs.Add(unsubscribe);
}
public void Unsubscribe(string key)
{
subscriptions.TryGetValue(key, out var subs);
if (subs != null)
{
foreach (var unsub in subs)
{
unsub();
}
subscriptions.Remove(key);
}
}
readonly Dictionary<string, List<Action>> subscriptions = new Dictionary<string, List<Action>>();
}
class Test
{
public event EventHandler<EventArgs> MyEvent;
public void RaiseEvent()
{
MyEvent?.Invoke(this, EventArgs.Empty);
}
}
}
假设您所有的事件处理程序都是void MyHandler(object sender, EventArgs e)
种类,您的字典将是Dictionary<string, Action<object,EventArgs>>
(假设您希望键是字符串 - 其他任何东西也可以)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.