[英]AddEventHandler using reflection to a static class
我需要向靜態類的現有事件添加新方法。 這是我的“貓”靜態類,無法更改,因為它是第三方。 我需要添加新方法以在同一事件myEvent
觸發。 此問題說明了如何對非靜態類執行此操作。 但是我不確定靜態類該怎么做。 有人幫忙嗎?
public static class Cat
{
internal static event EventHandler myEvent;
public static init()
{
....
....
}
}
class Dog
{
public static void init()
{
EventInfo eventInfo = typeof(Cat).GetEvent("myEvent");
if (eventInfo != null)
{
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, , newMethod); // I'm stuck here
eventInfo.AddEventHandler(, handler); // I'm stuck here
}
}
static void newMethod()
{
}
}
如果myEvent
是公共的,則可以執行Cat.myEvent+= new EventHandler(newMethod);
。 但不幸的是它是internal
您應該添加一些內容。 首先,將BindingFlags
添加到GetEvent
,因為該事件是靜態的並且是非公開的。 默認情況下, GetEvent
僅返回公共實例事件:
EventInfo eventInfo = typeof(Cat).GetEvent("myEvent", BindingFlags.Static | BindingFlags.NonPublic);
其次,使用CreateDelegate
另一重載來創建一個靜態方法的委托,該方法具有兩個參數。 或者使用您的參數,將null作為第二個參數。
第三,使用null
作為AddEventHandler
的第一個參數。 通常,您將實例作為第一個參數傳遞,但是由於此事件是靜態的,因此不需要實例:
eventInfo.AddEventHandler(null, handler);
您並沒有走的很遠,但是當您嘗試使用AddEventHandler()時,您將遇到很大的困難。 即使您嘗試通過反射破解事件,CLR也會強制事件的可訪問性。 而且由於它不是public
,所以反思將無濟於事。
您必須伸手去拿更大的武器。 假設事件不是自定義的,並且月亮在右象限中,則C#編譯器生成一個add訪問器方法。 這是一個名為add_myEvent()
的方法。 一定要使用反編譯器來驗證名稱,確保它實際上不是那樣命名的。
您要做的第一件事是為事件處理程序提供正確的簽名,該簽名與委托類型匹配:
static void newMethod(object sender, EventArgs e) {
// etc..
}
然后,您可以編寫反射代碼,如下所示:
public static void init() {
EventInfo eventInfo = typeof(Cat).GetEvent("myEvent",
BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo adder = typeof(Cat).GetMethod("add_myEvent",
BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo target = typeof(Dog).GetMethod("newMethod",
BindingFlags.NonPublic | BindingFlags.Static);
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, target);
adder.Invoke(null, new object[] { handler });
}
由於Dog在您的控制之下,因此不需要Delegate.CreateDelegate。
此代碼按預期工作:
namespace ConsoleApplication1
{
public static class Cat
{
internal static event EventHandler myEvent;
public static void RaiseEvent()
{
if (myEvent != null) myEvent(typeof(Cat), EventArgs.Empty);
}
}
class Dog
{
public static void init()
{
MethodInfo addInfo = typeof(Cat).GetMethod("add_myEvent", BindingFlags.NonPublic | BindingFlags.Static);
EventHandler handler = new EventHandler(Handler);
addInfo.Invoke(null, new object[] { handler });
}
static void Handler(object sender, EventArgs e)
{
Console.WriteLine("Event fired");
}
}
class Program
{
static void Main(string[] args)
{
Dog.init();
Cat.RaiseEvent();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.