【问题标题】:How to cast Object to Func and invoke?如何将 Object 转换为 Func 并调用?
【发布时间】:2014-06-07 16:31:11
【问题描述】:

我有一个泛型方法GetValueProvider,它返回泛型Func(Of...) 委托。在其他方法中,我需要调用GetValueProvider,调用返回的委托,最后得到它的返回值。但我不能直接调用它,因为我只获取类型作为参数。通过反射,我得到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)
...

有什么想法吗?谢谢。

【问题讨论】:

    标签: .net vb.net reflection delegates


    【解决方案1】:

    哦,我傻了。实际上,代码中使用的两种方法都有效。如果有人想知道,异常是由 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
    

    【讨论】:

      猜你喜欢
      • 2021-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 2019-09-04
      相关资源
      最近更新 更多