我有一个通用方法GetValueProvider
,返回通用Func(Of...)
委托。在其他方法中,我需要调用GetValueProvider
,调用返回的委托,并最终获得其返回值。但是我不能直接调用它,因为我只得到type作为参数。经过反思,我得到GetValueProvider
的输出不是问题,但我得到的是Object
。如何调用底层委托?
这是我的代码的简化示例。最后,我需要填充value
。
Protected Function GetValueProvider(Of T)() As Func(Of XmlNode, T, Func(Of Dictionary(Of String, String)), T)
' some code here
End Function
Public Function GetValue(valueType As Type) As Object
' value that should be set
Dim value As Object
' init some variables
Dim node As XmlNode = GetNode()
Dim defaultValue As Object = GetDefaultValue() ' type of defaultValue is always valueType
Dim tokensProvider As Func(Of Dictionary(Of String, String)) = GetTokensProvider()
Dim methodInfo = Me.GetType().GetMethod("GetValueProvider", Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.InvokeMethod)
Dim genericMethodInfo = methodInfo.MakeGenericMethod(valueType)
Dim valueProvider = genericMethodInfo.Invoke(Me, Nothing)
' following doesn't work and calling DynamicInvoke ends with an exception:
Dim valueProviderDelegate = DirectCast(valueProvider, [Delegate])
value = valueProviderDelegate.DynamicInvoke(node, defaultValue, tokensProvider)
' another approach that doesn't work (Invoke ends with the same exception):
Dim invokeMethodInfo = valueProvider.GetType().GetMethod("Invoke")
value = invokeMethodInfo.Invoke(valueProvider, New Object() {node, defaultValue, tokensProvider})
Return value
End Function
异常:System.ArgumentException: Object of type 'VB$AnonymousDelegate_2`1[System.Collections.Generic.Dictionary`2[System.String,System.String]]' cannot be converted to type 'System.Func`1[System.Collections.Generic.Dictionary`2[System.String,System.String]]'.
at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
...
任何想法?谢谢。
我真笨。实际上,代码中使用的两种方法都是有效的。如果有人想知道,异常是由tokensProvider中错误的类型引起的。上面的例子应该可以正常工作,我实际上在我的代码中是这样的:
Dim tokensProvider As = Function() As Dictionary(Of String, String)
' some code here
End Function
修复:
Dim tokensProvider As Func(Of Dictionary(Of String, String)) = Function() As Dictionary(Of String, String)
' some code here
End Function