在不知道泛型类型的情况下强制转换为泛型类型



我有一个使用泛型类型的接口(ValueControl(,另一个类(ValueControlHandler(使用该接口的实例。现在,当我在CreateHandler中创建ValueControlHandler时,我需要传递泛型类型。现在TCtrl"简单"(我只是使用ValueControl但不知道如何设置TVal.

Public Interface ValueControl(Of T)
ReadOnly Property Value As T
End Interface
Public Interface CtrlChanges
Function HasChanges() As Boolean
End Interface
Friend Class ValueControlHandler(Of TCtrl As ValueControl(Of TVal), TVal)
Implements CtrlChanges
....
End Class
Private Function DummyCreateHandler(Of TVal)(ByVal ctrl as ValueControl(Of TVal)) As CtrlChanges
Return New ValueControlHandler(Of ValueControl(Of TVal), TVal)(ctrl)
End Function
Private Function CreateHandler(ByVal ctrl As Object) As CtrlChanges
If TypeOf ctrl Is ValueControl(Of ValueControl(Of ???), ???) Then  ' <!--- Problem here
Return New ValueControlHandler(Of ValueControl(Of ???), ???)(ctrl)  ' <!--- Problem here
ElseIf Typeof ctrl Is AnotherType Then
Return New AnotherCtrlChanges(....)
Else
Return Nothing
End If
End Function

棘手的部分是,我什至不需要知道类型,因为我对CtrlChanges部分感兴趣。删除泛型并默认为Object的唯一解决方案是吗?我也用DummyCreateHandler尝试过,但后来我仍然不知道如何检查类型,它对第二次调用并没有多大帮助。

如果有帮助,以下是ValueControlHandler的完整类:

Friend Class ValueControlHandler(Of TCtrl As ValueControl(Of TVal), TVal)
Implements CtrlChanges
Protected ReadOnly Ctrl As TCtrl
Protected ReadOnly Val As TVal
Public Sub New(ByVal Ctrl As TCtrl)
Me.Ctrl = Ctrl
Me.Val = CurrentValue
End Sub
Public ReadOnly Property CurrentValue As TVal
Get
Return Ctrl.Value
End Get
End Property
Public Overridable Function HasChanges() As Boolean Implements CtrlChanges.HasChanges
Return CType(CurrentValue, Object) <> Val
End Function
End Class

您是否考虑过将工厂方法作为ValueControl的一部分? (旁注,接口上的"I"前缀是标准约定(

(注意,我的 VB.NET 有点生疏,希望你能理解这种方法的意图,尽管我有错别字(:

Public Interface IValueControl(Of T)
ReadOnly Property Value As T
ValueControlHandler(Of T) CreateValueControlHandler(ctrl As IValueControl(Of T))
End Interface

然后每个控件都可以生成自己的ValueControlHandler

Public Class MyControl Inherits Textbox Implements IValueControl(Of String)
Public Function ValueControlHandler(Of T) CreateValueControlHandler()
Return New ValueControlHandler(Of MyControl, String)(Me)
End Fucntion
End Class

CreateHandler可以将要参数化的类型作为参数。 然后,您将执行以下操作:

Private Function CreateHandler(ByVal ctrl As Object, ByVal TVal as Type) As CtrlChanges
'...
Dim genericValueControlType = GetType(ValueControl(Of )) 'Intentionally blank, the type is the unspecialized generic type.
Dim specificValueControlType = genericValueControlType.MakeGenericType(TVal)
'Untested, might need to be Is instead of =
If ctrl.GetType() = specificValueControlType Then
Dim genericHandlerType = GetType(ValueControlHandler(Of ) 'Untested, might need a comma to indicate two missing type params
Dim specificHandlerType = genericHandlerType.MakeGenericType(specificValueControlType, TVal)
Dim retval = specificHandlerType.GetConstructor({}).Invoke({})
Return CType(retval, CtrlChanges)
End If
End Function

根据工厂例程的详细程度,您还可以考虑基于反射和/或一个或多个约定进行构建。 遗憾的是,.NET 中缺少静态接口方法意味着约定是跨接口的不同实现调用逻辑Shared例程的唯一方法(无论如何,或者制作逻辑上Shared每个实例方法的东西,以便可以将其放在接口上;我都做了,两者都不完全令人满意(。

最新更新