假设我有以下代码:
Public Class MyDbTransaction
Implements IDbTransaction
Private itsTransaction As IDbTransaction
Public Sub New(ByVal trans As IDbTransaction)
If trans Is Nothing Then Throw New ArgumentNullException("trans")
itsTransaction = trans
End Sub
Public ReadOnly Property Base As IDbTransaction
Get
Return itsTransaction
End Get
End Property
<...all the other implementations go here...>
Public Shared Widening Operator CType(ByVal trans As MyDbTransaction) As SqlTransaction
If trans Is Nothing Then
Return Nothing
Else
Return CType(trans.Base, SqlTransaction)
End If
End Operator
End Class
如果在我的代码中某处:
Dim conn as New MyConnection(New SqlClient.SqlConnection("<ConnectionStringHere>"))
Dim Trn as IDbTransaction = conn.BeginTransaction()
Dim Cmd As System.Data.SqlClient.SqlCommand = CreateCommand(SqlText, Cnn, Trn)
Cmd.CommandTimeout = CommandTimeout
Cmd.Transaction = Trn 'Trn is of type MyDbTransaction and IT CRASHES HERE but I am expecting it to call MyDbTransaction.<Widening Operator CType(ByVal trans As MyDbTransaction) As SqlTransaction> to resolve this cast'
最后一行崩溃:
Unable to cast object of type 'MyDbTransaction' to type 'System.Data.SqlClient.SqlTransaction'
为什么不在这里调用Widening运算符?
Public Class MyConnection
Implements IDbConnection
Private itsConnection As IDbConnection
Protected Sub New(ByVal conn As IDbConnection)
If conn Is Nothing Then Throw New ArgumentNullException("conn")
itsConnection = conn
End Sub
Public Overridable Function BeginTransaction() As IDbTransaction Implements IDbConnection.BeginTransaction
return New MyDbTransaction(itsConnection.BeginTransaction())
End Function
Public Overridable Function BeginTransaction(ByVal il As IsolationLevel) As IDbTransaction Implements IDbConnection.BeginTransaction
return New MyDbTransaction(itsConnection.BeginTransaction(il))
End Function
<...all the other implementations go here...>
End Class
答案 0 :(得分:0)
我能提出的最好的解释是,为什么它不起作用是你的类不是继承自SqlTransaction,因此不会继承成员,因此,无法转换为基本实现的SqlTransaction。
这MSDN documentation间接解释了这一点:
“从派生类型到其基类型之一的转换正在扩大似乎令人惊讶。理由是派生类型包含基类型的所有成员,因此它有资格作为基类型的实例在相反的方向上,基类型不包含派生类型定义的任何新成员。“
因为您的类实现了IDbTransaction,所以您可以成功地分配给任何需要此接口的属性,但由于它不继承SqlTransaction,您可能无法将其分配给任何需要SqlTransaction的属性或参数。
我认为从SqlTransaction继承或使用Extension Methods来实现所需的功能会更有意义。