动态类型转换会为相同的事件处理程序签名引发异常异常?

时间:2017-07-10 23:22:18

标签: vb.net casting delegates

Imports System
Imports System.Reflection
Imports System.Reflection.Emit 
'Static type casting ..... Success!
Dim a = CType(Sub(sender As Control, e As ColumnWidthChangedEventArgs)
                   foo()
              End Sub, System.Windows.Forms.ColumnWidthChangedEventHandler)
'Extracting windows.forms assembly namespace .....
Dim assemblyname As String = ""
For Each assem As Assembly In AppDomain.CurrentDomain.GetAssemblies()
   If (assem.GetName().Name = "System.Windows.Forms") Then
         assemblyname = assem.FullName
         Exit For
   End If
Next
'Dynamic type casting ..... Fail!
a = CTypeDynamic(Sub(sender As object, e As ColumnWidthChangedEventArgs)
                    foo()
                 End Sub,
                 Assembly.Load(assemblyname).GetType("System.Windows.Forms.ColumnWidthChangedEventHandler"))

第二次分配失败了System.InvalidCastException,我试过了:

a = CTypeDynamic(New listview,
                 Assembly.Load(assemblyname).GetType("System.Windows.Forms.ListView"))

一切看起来都很好,类型是同源的,汇编文件是兼容的,这里的不匹配或误用在哪里?

错误详情:

大会名称

  

Microsoft.VisualBasic.CompilerServices.Conversions

     

Microsoft.VisualBasic,Version = 10.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a

错误上下文:

  

转换类型' VB $ AnonymousDelegate_4(Of Object,ColumnWidthChangedEventArgs)'键入' ColumnWidthChangedEventHandler'无效

1 个答案:

答案 0 :(得分:1)

最初我认为CTypeDynamic在幕后工作的方式与您的签名不匹配的事实有所不同。

但它看起来像.Net Framework中的一个错误,它在编译时已知的类型没有任何结果。

我改变了你的签名:

Function(sender As Control, e As ColumnWidthChangedEventArgs)

到正确的一个:

Sub(sender As object, e As ColumnWidthChangedEventArgs)

但即使您在使用CType的Generic方法中使用正确的签名,也会发生同样的错误。此外,您甚至无法使用TryCast。

Public Function ConvertGenericType(Of T)(obj As Object) As T
    Return CType(obj, T)
End Function

Public Sub RunTest()

    ''public delegate void ColumnWidthChangedEventHandler(object sender, ColumnWidthChangedEventArgs e)

    Dim MyDelegate = Sub(sender As Object, e As ColumnWidthChangedEventArgs)
                         Console.WriteLine("FOO")
                     End Sub
    'Works
    Dim CastOne = CType(MyDelegate, ColumnWidthChangedEventHandler)

    'Works
    Dim CastTwo As ColumnWidthChangedEventHandler = MyDelegate

    'Works
    Dim CastThree As ColumnWidthChangedEventHandler = Sub(sender As Object, e As ColumnWidthChangedEventArgs)
                                                          Console.WriteLine("FOO")
                                                      End Sub

    ' Blows Up
    Dim CastFour = ConvertGenericType(Of ColumnWidthChangedEventHandler)(MyDelegate)
    ' Exception: System.InvalidCastException: 'Unable to cast object of type VB$AnonymousDelegate_0`2[System.Object,System.Windows.Forms.ColumnWidthChangedEventArgs]'
    '    to type 'System.Windows.Forms.ColumnWidthChangedEventHandler'.'

    ' Won't Compile: ColumnWidthChangedEventHandler
    'TryCast(MyDelegate, ColumnWidthChangedEventHandler)
    'Sub <generated method>(sender As Object, e As ColumnWidthChangedEventArgs) can't be converted to  o type 'System.Windows.Forms.ColumnWidthChangedEventHandler'
End Sub