Нет необходимости в дженериках. Просто используйте наследование:
' abstract base class; you could possibly declare it as an interface instead: '
MustInherit Class CsvField
Public MustOverride Function Export() As String
End Class
' specialized class for alpha-numeric fields: '
Class AlphaCsvField : Inherits CsvField
...
Public Overrides Function Export() As String
Return String.Format("""{0}""", value)
End Function
Private value As String
End Class
' specialized class for bool fields '
Class BoolCsvField : Inherits CsvField
...
Public Overrides Function Export() As String
If value = True Then
Return "True"
Else
Return "False"
End If
End Function
Private value As Boolean
End Class
...
В примере кода предполагается, что value
хранит фактическое значение поля. Надеюсь этот пример достаточно понятен. Сделайте свою коллекцию полей единичной для типа базового класса, например List(Of CsvField)
. Затем он также может содержать объекты всех производных типов.
Кстати, обратите внимание, как при использовании полиморфизма вы можете полностью избавиться от перечисления FieldType
и всех конструкций If
/ Select Case
, которые решают, что делать в зависимости от на поле типа. Если вам все еще нужно это сделать, вы можете заменить:
If someCsvField.FieldType = Alpha Then ...
с
If TypeOf someCsvField Is AlphaCsvField Then ...
Однако вы, как правило, должны иметь возможность перемещать такую логику в производные классы и избавляться от операторов If
путем переопределения методов. В этом весь смысл приведенного выше примера.
P.S.: На случай, если вам интересно, как вы создаете CsvField
объекты без явной проверки типа. Один из способов - использовать фабричные методы и методы перегрузки:
MustInherit Class CsvField
Public Shared Function Create(value As String) As CsvField
Return New AlphaCsvField(value)
End
Public Shared Function Create(value As Boolean) As CsvField
Return New BoolCsvField(value)
End
...
' as in the above code example '
Public MustOverride Function Export() As String
End Class
Например, CsvField.Create(False)
создаст BoolCsvField
, «замаскированный» под CsvField
, так что вы можете поместить его в List(Of CsvField)
или любую другую коллекцию.