无法通过 VS2015 上的反射绑定到事件
Cannot bind to event via reflection on VS2015
我有一段代码使用 DbDataAdapter
.
从 DataTable
填充数据库 table
DbDataAdapter
是通过 DbProviderFactory.CreateDataAdapter
方法创建的,其中 DbProviderFactory
由 Devart dotConnect 提供。
我们使用 Devart 的 Oracle、SqlServer 和 Postgres 驱动程序。
因为我的 DataTable
中有将近 10 万行,我需要绑定到 RowUpdated
事件(以更新进度条),不幸的是,尽管它没有在公共接口上定义在所有提到的数据库驱动程序中都可用。
因此我用这段代码通过反射绑定它:
Dim eventInfo As System.Reflection.EventInfo = adapter.GetType().GetEvent("RowUpdated")
eventInfo.AddEventHandler(adapter, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
(Sub(s As Object, e As EventArgs) UpdateProgress(s, e)).Method))
如果使用 VS2013 编译,这将完美运行,但如果在 Roslyn (VS2015) 上编译,在运行时失败,但有以下例外:
Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type
对此有任何帮助吗?
使用 Devart.Data.PostgreSql.PgSqlRowUpdatedEventHandler
(我目前使用的是 Postgres)作为 e
的类型都行不通。
从@djv 在评论中发表的this answer开始,我终于找到了罪魁祸首。
看来,对于 Roslyn (VS2015),您需要在绑定事件处理程序之前显式声明 Delegate
。
例如,在我的例子中,我需要写:
Public Delegate Sub RowUpdatedEventHandler(sender As Object, e As RowUpdatedEventArgs)
然后:
Dim eventInfo As System.Reflection.EventInfo = adpt.GetType().GetEvent("RowUpdated")
eventInfo.AddEventHandler(adpt, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
DirectCast(AddressOf UpdateProgress, RowUpdatedEventHandler).Method))
而且它似乎与 lamdas 有一些问题。例如,这不起作用:
Dim eventInfo As System.Reflection.EventInfo = adpt.GetType().GetEvent("RowUpdated")
eventInfo.AddEventHandler(adpt, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
DirectCast((Sub(s As Object, e As RowUpdatedEventArgs) UpdateProgress(s, e)), RowUpdatedEventHandler).Method))
(在 lambda 表达式上有或没有 DirectCast
)
我有一段代码使用 DbDataAdapter
.
DataTable
填充数据库 table
DbDataAdapter
是通过 DbProviderFactory.CreateDataAdapter
方法创建的,其中 DbProviderFactory
由 Devart dotConnect 提供。
我们使用 Devart 的 Oracle、SqlServer 和 Postgres 驱动程序。
因为我的 DataTable
中有将近 10 万行,我需要绑定到 RowUpdated
事件(以更新进度条),不幸的是,尽管它没有在公共接口上定义在所有提到的数据库驱动程序中都可用。
因此我用这段代码通过反射绑定它:
Dim eventInfo As System.Reflection.EventInfo = adapter.GetType().GetEvent("RowUpdated")
eventInfo.AddEventHandler(adapter, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
(Sub(s As Object, e As EventArgs) UpdateProgress(s, e)).Method))
如果使用 VS2013 编译,这将完美运行,但如果在 Roslyn (VS2015) 上编译,在运行时失败,但有以下例外:
Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type
对此有任何帮助吗?
使用 Devart.Data.PostgreSql.PgSqlRowUpdatedEventHandler
(我目前使用的是 Postgres)作为 e
的类型都行不通。
从@djv 在评论中发表的this answer开始,我终于找到了罪魁祸首。
看来,对于 Roslyn (VS2015),您需要在绑定事件处理程序之前显式声明 Delegate
。
例如,在我的例子中,我需要写:
Public Delegate Sub RowUpdatedEventHandler(sender As Object, e As RowUpdatedEventArgs)
然后:
Dim eventInfo As System.Reflection.EventInfo = adpt.GetType().GetEvent("RowUpdated")
eventInfo.AddEventHandler(adpt, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
DirectCast(AddressOf UpdateProgress, RowUpdatedEventHandler).Method))
而且它似乎与 lamdas 有一些问题。例如,这不起作用:
Dim eventInfo As System.Reflection.EventInfo = adpt.GetType().GetEvent("RowUpdated")
eventInfo.AddEventHandler(adpt, [Delegate].CreateDelegate(eventInfo.EventHandlerType,
DirectCast((Sub(s As Object, e As RowUpdatedEventArgs) UpdateProgress(s, e)), RowUpdatedEventHandler).Method))
(在 lambda 表达式上有或没有 DirectCast
)