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);
}

哦,天哪,我不知道的名字是什么!太棒了。谢谢。哦,天哪,我不知道的名字是什么!太棒了。谢谢。是的,这正是我想做的,但在运行时是动态的。自动化的原因是因为我有数百个事件要以这种方式进行调整,不想全部手工编写。是的,这正是我想要做的,但在运行时是动态的。之所以实现自动化,是因为我有数百个事件需要以这种方式进行调整,不想全部手工编写。