Динамическая обработка типов полей - PullRequest
1 голос
/ 02 апреля 2010

Я должен сделать экспорт из БД в CSV. ( .NET 2 )

field; fileld; field... etc

Имеют 3 типа полей: Альфа , Числовые и Bool , представленные как "alphaValue", intValue и True/False.

Я пытаюсь инкапсулировать это в коллекцию полей , чтобы экспортировать, если alpha, а затем установить "", если Bool => True / False, если числовое значение равно как есть.

и попробуйте построить CsvField класс:

  Public Structure?Class CsvField(Of T As ???)

  End Structure

  Enum FieldType
    Alpha
    Bool
    Numeric
  End Enum

возможное использование:

myCollection.Add(new CsvField(DateTime.Now, FileType.Alpha))
myCollection.Add(new CsvField(myInt, FileType.Numeric))

приветствуются любые предложения.

1 Ответ

2 голосов
/ 02 апреля 2010

Нет необходимости в дженериках. Просто используйте наследование:

' 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) или любую другую коллекцию.

...