C# 如何以编程方式检索事件的EventInfo而不硬编码其名称?
给定一个接口:C# 如何以编程方式检索事件的EventInfo而不硬编码其名称?,c#,.net,reflection,C#,.net,Reflection,给定一个接口: IEventProvider { event EventHandler<string> StringAvailable; void RequestString(); } IEventProvider { 事件处理程序字符串可用; void RequestString(); } 我想通过如下方法为StringAvailable检索EventInfo:EventInfo ei=GetEventInfo(providerInstance.StringA
IEventProvider
{
event EventHandler<string> StringAvailable;
void RequestString();
}
IEventProvider
{
事件处理程序字符串可用;
void RequestString();
}
我想通过如下方法为StringAvailable
检索EventInfo
:EventInfo ei=GetEventInfo(providerInstance.StringAvailable)
或类似的方法。我不想传递包含其名称的字符串
我试图滥用lambda和表达式树来提取传入事件的名称,但没有效果。因为事件不是C#中的头等成员,这被证明是困难的。我只是帮助找到一种在运行时获取事件名称的方法,代码可以由编译器进行静态验证,以确保事件在编译时存在
我现在的解决方法是从我想要使用的类中删除所有事件,并将它们更改为操作
。但这并不理想
对于那些想知道我为什么要这样做的人,我想允许使用基于事件的异步模式的类在运行时使用IL生成自动调整为异步/等待。在上面的示例界面中,适配器将使用
DynamicMethod
包装RequestString
和StringAvailable
并公开公共异步任务RequestStringAsync()
,如果我理解正确,我将编写这样的扩展方法
public static class Ext
{
public static Task<string> RequestStringAsync(this IEventProvider cls)
{
var tcs = new TaskCompletionSource<string>();
EventHandler<string> handler = null;
handler = (o, s) =>
{
tcs.SetResult(s);
cls.StringAvailable -= handler;
};
cls.StringAvailable += handler;
cls.RequestString();
return tcs.Task;
}
}
如果我理解正确的话,我会写一个这样的扩展方法
public static class Ext
{
public static Task<string> RequestStringAsync(this IEventProvider cls)
{
var tcs = new TaskCompletionSource<string>();
EventHandler<string> handler = null;
handler = (o, s) =>
{
tcs.SetResult(s);
cls.StringAvailable -= handler;
};
cls.StringAvailable += handler;
cls.RequestString();
return tcs.Task;
}
}
您可以将ProviderInfo实例传递给一个方法,该方法可以获取每个反射的EventInfo 以下是三个例子:
var singleEvent = GetEventInfo(providerInstance);
public static EventInfo GetEventInfo(IEventProvider eventProvider)
{
var type = eventProvider.GetType();
return type.GetEvent(nameof(eventProvider.StringAvailable));
}
这一个获取带有操作符硬编码名称的事件
var singleEventWithName = GetEventInfo(providerInstance, nameof(providerInstance.StringAvailable));
public static EventInfo GetEventInfo(IEventProvider eventProvider, string name)
{
var type = eventProvider.GetType();
return type.GetEvent(name);
}
var allEvents = GetEventInfos(providerInstance);
public static EventInfo[] GetEventInfos(IEventProvider eventProvider)
{
return eventProvider.GetType().GetEvents();
}
在这里,您可以将名称与操作员的名称一起传递
var singleEventWithName = GetEventInfo(providerInstance, nameof(providerInstance.StringAvailable));
public static EventInfo GetEventInfo(IEventProvider eventProvider, string name)
{
var type = eventProvider.GetType();
return type.GetEvent(name);
}
var allEvents = GetEventInfos(providerInstance);
public static EventInfo[] GetEventInfos(IEventProvider eventProvider)
{
return eventProvider.GetType().GetEvents();
}
这个函数只返回提供者的所有事件信息
我希望这有帮助
编辑
最好是:
var eventInfo = GetEventInfo(nameof(providerInstance.StringAvailable));
public static EventInfo GetEventInfo(string name)
{
return typeof(IEventProvider).GetEvent(name);
}
您可以将ProviderInfo实例传递给一个方法,该方法可以获取每个反射的EventInfo 以下是三个例子:
var singleEvent = GetEventInfo(providerInstance);
public static EventInfo GetEventInfo(IEventProvider eventProvider)
{
var type = eventProvider.GetType();
return type.GetEvent(nameof(eventProvider.StringAvailable));
}
这一个获取带有操作符硬编码名称的事件
var singleEventWithName = GetEventInfo(providerInstance, nameof(providerInstance.StringAvailable));
public static EventInfo GetEventInfo(IEventProvider eventProvider, string name)
{
var type = eventProvider.GetType();
return type.GetEvent(name);
}
var allEvents = GetEventInfos(providerInstance);
public static EventInfo[] GetEventInfos(IEventProvider eventProvider)
{
return eventProvider.GetType().GetEvents();
}
在这里,您可以将名称与操作员的名称一起传递
var singleEventWithName = GetEventInfo(providerInstance, nameof(providerInstance.StringAvailable));
public static EventInfo GetEventInfo(IEventProvider eventProvider, string name)
{
var type = eventProvider.GetType();
return type.GetEvent(name);
}
var allEvents = GetEventInfos(providerInstance);
public static EventInfo[] GetEventInfos(IEventProvider eventProvider)
{
return eventProvider.GetType().GetEvents();
}
这个函数只返回提供者的所有事件信息
我希望这有帮助
编辑
最好是:
var eventInfo = GetEventInfo(nameof(providerInstance.StringAvailable));
public static EventInfo GetEventInfo(string name)
{
return typeof(IEventProvider).GetEvent(name);
}
哦,天哪,我不知道的名字是什么!太棒了。谢谢。哦,天哪,我不知道的名字是什么!太棒了。谢谢。是的,这正是我想做的,但在运行时是动态的。自动化的原因是因为我有数百个事件要以这种方式进行调整,不想全部手工编写。是的,这正是我想要做的,但在运行时是动态的。之所以实现自动化,是因为我有数百个事件需要以这种方式进行调整,不想全部手工编写。