我努力让.Net反思能够解决以下问题...
(以下是VB.Net
,但我已将此标记为C#
,希望能够从更广泛的受众群体中找到答案。如果C#
回答由于语言限制,无法转换为VB.Net
,至少我知道如果需要,我可以在C#
重新编写它。)
我正在编写.Net 4.5.2 DLL,我可以将其放入现有的ASP.NET 4.5.2生产网站,因此我不需要重建网站。在新的DLL中,我使用Reflection来查找一个类,添加一个事件委托,然后调用一个方法。
我遇到的问题是事件委托需要绑定到具有参数类的本地函数,该参数类也需要通过反射找到。
在现有的无法重建的DLL中,我有以下内容(以下内容已在此处手写,未复制,因此可能包含较小的错别字)...
Public Class OldClass
' A nested class used for the eventargs of the event
Public Class OldClassEventArgs
Inherits EventArgs
Public Property MiscArgs As String = ""
End Class
' Event delegate
Public Delegate Sub OldClassEventDelegate(ByVal e As OldClassEventsArgs)
' The event itself
Public Event OldClassEvent As OldClassEventDelegate
' A method that does things and then raises the event
Public Sub OldClassMethod(Byval arg1 As String)
RaiseEvent OldClassEvent(New OldClassEventArgs())
End Sub
End Class
在新的DLL中,我希望能够创建OldClass
的实例,将事件处理程序绑定到OldClassEvent
并调用OldClassMethod
...结果是本地的调用事件处理程序,参数是OldClassEventArgs
...
Public Class MyPage
Inherits System.Web.UI.Page
Public Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' Gets the assembly for the existing website DLL
Dim assem As Assembly = GetAssembly()
' Get the type of the class in the existing website
Dim oldClassType As Type = assem.GetType("OldClass", False, True)
' Create an instance of the class
Dim oldClassObj as Object = Activator.CreateInstance(oldClassType, False)
' Get the LOCAL event handler
Dim eventMethod As MethodInfo = Me.GetType().GetMethod("LocalEventHandler", BindingFlags.NonPublic Or BindingFlags.Instance)
' Get the event info
Dim eventInf As EventInfo = logonType.GetEvent("OldClassEvent")
' Create the delegate
Dim del As [Delegate] = [Delegate].CreateDelegate(eventInf.EventHandlerType, oldClassObj, eventMethod)
' Add the delegate to the event
eventInf.AddEventHandler(classObj, del)
' Get the method to call
Dim methodInf as MethodInfo = logonType.GetMethod("OldClassMethod", BindingFlags.Public Or BindingFlags.Instance)
' Call it
methodInf.Invoke(oldClassObj, New Object() { "foobar" })
End Sub
' The following CANNOT happen, because OldClassEventArgs needs to be found via reflection!
Protected Sub LocalEventHandler(ByVal e As OldClass.OldClassEventArgs)
' Do something with e.MiscArgs
End
End Class
正如您在上面的代码中所看到的,我无法使用OldClass.OldClassEventsArgs
,因为它在当前上下文中并不存在...只能通过反射。
如何使用通过反射找到的类作为参数创建方法?
即使我有本地处理程序[{1}},我仍然会遇到运行时错误...
无法绑定到目标方法,因为其签名或安全透明度与委托类型的方法不兼容。
...创建ByVal e As Object
。
更新
基于@jmcilhinney的评论,我还尝试了以下方法声明(使用Delgate
),它仍然会导致与之前相同的运行时错误...
EventArgs
答案 0 :(得分:1)
创建委托实例时,我们需要使用包含委托方法的实例。
eventMethod => MethodInfo(LocalEventHandler)位于MyPage类上。
你需要改变
Dim del As [Delegate] = [Delegate].CreateDelegate(eventInf.EventHandlerType, oldClassObj, eventMethod)
到
Dim del As [Delegate] = [Delegate].CreateDelegate(eventInf.EventHandlerType, Me, eventMethod)