gpt4 book ai didi

c# - 在运行时使用反射检查给定事件是否被订阅

转载 作者:太空狗 更新时间:2023-10-30 01:26:17 27 4
gpt4 key购买 nike

考虑一个有一些事件的类。这个事件列表将会增长。有些是可选的。其他为必填项。

为了简化一些初始验证,我有一个自定义属性,将事件标记为必需事件。例如:

    [RequiredEventSubscription("This event is required!")]
public event EventHandler ServiceStarted;

到目前为止一切顺利。为了验证所有事件,我使用反射迭代事件列表并获取自定义属性。但我需要一种方法来确定该事件是否已订阅。

没有反射,ServiceStarted.GetInvocationList 就完成了这项工作。但事件必须来自这个列表:var eventList = this.GetType().GetEvents().ToList();

有什么方法可以检查事件列表中的给定事件是否已使用反射订阅?

--[更新]--这是基于 Ami 的回答的可能解决方案:

    private void CheckIfRequiredEventsAreSubscribed()
{
var eventList = GetType().GetEvents().ToList().Where(e => Attribute.IsDefined(e, typeof(RequiredEventSubscription)));

StringBuilder exceptionMessage = new StringBuilder();
StringBuilder warnMessage = new StringBuilder();

foreach (var evt in eventList)
{
RequiredEventSubscription reqAttr = (RequiredEventSubscription) evt.GetCustomAttributes(typeof(RequiredEventSubscription), true).First();
var evtDelegate = this.GetType().GetField(evt.Name, BindingFlags.Instance | BindingFlags.NonPublic);
if (evtDelegate.GetValue(this) == null)
{
warnMessage.AppendLine(reqAttr.warnMess);
if (reqAttr.throwException) exceptionMessage.AppendLine(reqAttr.warnMess);
}
}
if (warnMessage.Length > 0)
Console.WriteLine(warnMessage);
if (exceptionMessage.Length > 0)
throw new RequiredEventSubscriptionException(exceptionMessage.ToString());
}

非常感谢!!

最佳答案

这里有一些主要的设计问题。通常,没有办法询问一个对象它的事件订阅者是谁。很少有人会想要这个功能,但如果你真的想要它,你应该让类以某种方式公开它,例如,通过使用如下方法实现接口(interface):

public IEnumerable<Delegate> GetSubscribers(string eventName);

无论如何,要回答所问的问题,您可以使用反射,但前提是您确切知道订阅者是如何维护的。例如,假设所有事件都是用 C# 类字段事件的当前实现实现的,您可以执行类似(强烈不鼓励)的操作:

object o = ...

var unsubscribedEvents =
from e in o.GetType().GetEvents()
where Attribute.IsDefined(e, typeof(RequiredEventSubscriptionAttribute))
let field = o.GetType()
.GetField(e.Name, BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(o)
where field == null
select field;

var isValid = !unsubscribedEvents.Any();

关于c# - 在运行时使用反射检查给定事件是否被订阅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5313694/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com