我正在实现一个需要传递运行时未知的特定委托类型的函数。我想返回一个将ParamArray作为唯一参数的泛型方法(该方法将用于调用另一个方法,为其参数传递ParamArray)。
使用'真实'委托,以下代码工作正常:
Public Sub OnEvent(ParamArray params())
'Do work
End Sub
Function SomeFunc()
Return New RoutedEventHandler(AddressOf OnEvent)
End Function
即使OnEvent与RoutedEventHandler的参数不匹配,这仍然有效 - 编译器可以使用ParamArray,并正确传递参数。
然而,当使用CreateDelegate时,运行时会抱怨该参数不匹配:
Function SomeFunc()
Return [Delegate].CreateDelegate(GetType(RoutedEventHandler), Me, "OnEvent")
End Function
实际代码将在运行时获取委托类型,因此我需要使用CreateDelegate。有没有办法做到这一点?
答案 0 :(得分:0)
我根据similar SO question的答案编写了以下代码,修改了VB并更简洁:
Imports System.Linq.Expression.Expressions 'this might only work in VS2015. You can use a explicit name instead, i.e. Expressions.Call, Expressions.Lambda
Public Shared Function GetDynamicDelegate(delegateType As Type, method As Action(Of Object())) As [Delegate]
Dim invokeMethod = delegateType.GetMethod("Invoke")
Dim params = invokeMethod.GetParameters.Select(Function(p) Parameter(p.ParameterType, p.Name)).ToArray
Dim instance = If(method.Target Is Nothing, Nothing, Constant(method.Target)) 'Pass Nothing when Shared
Dim body = [Call](instance, method.Method, NewArrayInit(GetType(Object), params))
Return Lambda(delegateType, body, params).Compile
End Function
(原来是一个额外的线投射到Object(),但是这个是自动完成的,所以我把它留了出来)
此功能仅采用方法As Action(..)。您可以将它实现为func作为Func(...),但是它只会为该参数获取一个函数。