我有一个使用泛型类型的接口(ValueControl
),还有另一个使用该接口实例的类(ValueControlHandler
)。现在,当我在ValueControlHandler
中创建CreateHandler
时,我需要传递通用类型。现在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
答案 0 :(得分:0)
您是否考虑过将工厂方法作为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
答案 1 :(得分:0)
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
无论如何都可以使用实例化方法,以便可以将其放在接口上;我已经完成了这两项工作,但都不是完全令人满意的。)