我有一个带有一个类的程序集,该类使用委托和自定义事件args定义了一个自定义事件。现在,我必须通过代码动态加载此程序集,并创建此类的实例。到这里我很好。现在,我必须使用自定义委托为类对象引发的事件提供事件处理程序。如何使用反射将事件处理程序添加到从类引发的事件中?
这是执行此操作的代码:
class Program
{
static void Main(string[] args)
{
// Create publisher.
var pub = Activator.CreateInstance(typeof(Publisher));
// Get the event.
var addEvent = typeof(Publisher).GetEvent("Event");
// Create subscriber.
var sub = Activator.CreateInstance(typeof(Subscriber));
// Get the method.
var handler = typeof(Subscriber).GetMethod("Handle");
// Create a valid delegate for it.
var handlerDelegate = MakeEventHandlerDelegate(handler, sub);
// Add the event.
addEvent.AddEventHandler(pub, handlerDelegate);
// Call the raise method.
var raise = typeof(Publisher).GetMethod("Raise");
raise.Invoke(pub, new object[] { "Test Value" });
Console.ReadLine();
}
static Delegate MakeEventHandlerDelegate(MethodInfo methodInfo, object target)
{
ParameterInfo[] info = methodInfo.GetParameters();
if (info.Length != 2)
throw new ArgumentOutOfRangeException("methodInfo");
if (!typeof(EventArgs).IsAssignableFrom(info[1].ParameterType))
throw new ArgumentOutOfRangeException("methodInfo");
if (info[0].ParameterType != typeof(object))
throw new ArgumentOutOfRangeException("methodInfo");
return Delegate.CreateDelegate(typeof(EventHandler<>).MakeGenericType(info[1].ParameterType), target, methodInfo);
}
}
class Args : EventArgs
{
public string Value { get; set; }
}
class Publisher
{
public event EventHandler<Args> Event;
public void Raise(string value)
{
if (Event != null)
{
Args a = new Args { Value = value };
Event(this, a);
}
}
}
class Subscriber
{
public void Handle(object sender, Args args)
{
Console.WriteLine("Handle called with {0}.", args.Value);
}
}
事件是多播委托,您将以System.Delegate的类型检索该事件,请使用Delegate.Combine组合两个实例,然后将委托设置为组合的委托。
C#为此具有很好的速记语法:
class SomeClass
{
public event Action<string> TextEvent;
}
[您可能会这样写:(我有点懒,不会检查,您必须自己解决问题)
var obj = // instance of SomeClass...
var t = typeof(SomeClass); // you need the type object
var member = t.GetEvent("TextEvent");
member.AddEventHandler(obj, new Action<string>(delegate(string s)){}); // done!
我以前曾经做过,真是太痛苦了-最终遇到了这个tutorial。
是否有可能在另一个程序集中有一个接口,您可以使用该接口通过反射连接事件?只是一个想法...
我可能会丢失一些内容,但是如果您知道该事件的名称和签名,则需要知道该事件的类型,然后大概知道该事件的类型。在这种情况下,为什么需要使用反射?只要您具有正确键入的引用,就可以按常规方式附加处理程序。
• 如何在 Python FMX GUI 应用程序中为 TabControl 设置活动选项卡?
• 如何使用Node Express和Sequelize Postgress实现屏蔽用户功能
• 二维码扫描相机在 android studio 中无法正常工作
• Azure ForEach Activity with GetMetadata 和 Set Variable Pipeline Expression Builder
• 这段代码可以用更少的“with”“End With”语句精简吗>?
• 如何使用xamarin forms获取移动应用程序中运行的应用程序列表?我试过使用 GetRunningTasks 但它已经过时了
• 如何在 C++ 中读取所有奇数? 50 读为真。不知道为什么 [关闭]