現在我只能將 Jumper 類用于“Something”型別的物件。我嘗試將它重寫為泛型類,但在從我的 SomeForm 類中實際呼叫它時遇到了困難,因為“T”可能是我只在運行時才知道的幾種型別之一。我讀到這意味著我基本上是在與整個泛型語言設計作斗爭。
示例代碼是 VB,但我也可以使用 C# 答案。
問題:這可以用泛型重新設計嗎?或者在我的情況下,什么是泛型的更好替代品?
Public Class Jumper
Private _enumeratorForwards As IEnumerator(Of Something)
Public Sub JumpNext(functions As FunctionCombi)
Forwards(functions.SelectorFunc)
End Sub
Private Iterator Function Forwards(selectorFunc As Func(Of Something, Boolean)) As IEnumerable(Of Something)
End Class
Public Class FunctionCombi
Public Property SelectorFunc As Func(Of Something, Boolean)
Sub New(_selectorFunc As Func(Of Something, Boolean))
SelectorFunc = _selectorFunc
End Sub
End Class
Public Class SomeForm
'x and y would be different types
Private _functionCombis As New Dictionary(Of SomeEnum, FunctionCombi) From {
{SomeEnum.A, New FunctionCombi(Function(x) RunSomeFunction(x)},
{SomeEnum.B, New FunctionCombi(Function(y) RunSomeOtherFunction(y))}
Private Sub SomeHandler(sender as object, e as EventArgs)
For i = 1 To [Enum].GetValues(GetType(SomeEnum)).Length
'The type I would need here differs and I only know it at runtime
Dim functionInfo As FunctionCombi = Nothing
If Not _functionCombis.TryGetValue(i, functionInfo) Then Continue For
Dim jumper As Jumper = sender.Tag(2)
Next
End Sub
End Class
uj5u.com熱心網友回復:
泛型型別很可能不是您需要的,因為它們是在compile time中解決的。對于要在運行時決議的不同型別,請使用介面。
如果一個人可以完全控制所涉及的型別,那只是意味著:定義一個介面并讓兩種型別都實作該介面。
Public Interface IOfficeObject
' any members that Shape and TextRange have in common
End Interface
Public Interface Shape
Inherits IOfficeObject
' any members specific for Shape
End Interface
Public Interface TextRange
Inherits IOfficeObject
' any members specific for TextRange
End Interface
然后Jumper只需與該介面對話,而不用關心底層實作。
Jumper 不應該關心那些基礎類,否則它將違背將兩個類放在同一個IEnumerator.
Public Class Jumper
Private _enumeratorForwards As IEnumerator(Of IOfficeObject)
...
End Class
您沒有解釋什么Shape和TextRange(以及您可能感興趣的任何其他 MS 介面)有什么共同點,您也沒有解釋您的代碼將對這些物件采取什么樣的操作。這是一種恥辱,因為這意味著我必須用一些假設的例子來說明我的觀點。
讓我們假設Shape并TextRange有以下共同點:
Application型別的屬性Application,類似于此- 一個方法
Copy,類似于這個
這使我的通用界面:
Public Interface IOfficeObject
ReadOnly Property Application As Application
Sub Copy()
End Interface
不幸的是,您無法控制Shapeand TextRange; 它們是微軟定義的介面。顯然,微軟并沒有費心去定義一個共同的介面來同時被Shape和繼承TextRange。我不知道為什么;我不熟悉這些界面或它們的歷史。這可能是一個疏忽,變成了遺產。
您可以使用配接器模式來解決該問題。
Public Class ShapeAdapter
Implements IOfficeObject
Private ReadOnly _shape As Shape
Public Sub New(shape As Shape)
_shape = shape
End Sub
Public ReadOnly Property Application As Application
Get
Return _shape.Application
End Get
End Property
Public Sub Copy()
_shape.Copy()
End Sub
' Any other members, forwarding to _shape
End Class
Public Class TextRangeAdapter
Implements IOfficeObject
Private ReadOnly _textRange As TextRange
Public Sub New(textRange As TextRange)
_textRange = textRange
End Sub
Public ReadOnly Property Application As Application
Get
Return _textRange.Application
End Get
End Property
Public Sub Copy()
_textRange.Copy()
End Sub
' Any other members, forwarding to _textRange
End Class
產生可列舉的物件涉及將每個物件包裝在其配接器類中。例子:
Dim listOfOfficeObjects As New List(Of IOfficeObject)
listOfOfficeObjects.Add(New ShapeAdapter(shape1))
listOfOfficeObjects.Add(New TextRangeAdapter(textRange1))
listOfOfficeObjects.Add(New ShapeAdapter(shape2))
listOfOfficeObjects.Add(New TextRangeAdapter(textRange2))
(如果您更喜歡工廠而不是 and 的顯式實體化ShapeAdapter,TextRangeAdapter那當然可以。)
Class Jumper will retrieve these adapters.
Consumers will always be talking to these adapters, through interface IOfficeObject.
In your own code sample, I recognize two consumers, but I'm sure there will be more in the solution you are working on.
Public Function RunSomeFunction(obj As IOfficeObject) As Boolean
' pulling whatever is necessary from IOfficeObject to come to a return value
End Function
Public Function RunSomeOtherFunction(obj As IOfficeObject) As Boolean
' likewise
End Function
If a consumer needs anything from Shape or TextRange that is not exposed by the interface and/or not implemented by the adapters,
then that is something that needs to be fixed in the interface and the adapters.
If it cannot be implemented by the adapters, then there is a flaw in your architecture.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/437881.html
上一篇:可以用不同的約束子型別實體化
