"(без ручного копирования всех свойств из одного в другой)"
В самом деле?
Я думаю, что в тот или иной момент вам придется писать более сложный код, делая это ...
Сериализовать/Deserialize ... удобный способ в большинстве случаев. Я использовал это .. до тех пор, пока я не добавил Свойство в класс, не добавляя их коллег в других. Классы типа Point2D
с X и Y как двойной, Vector2D
с X и Y как двойной или Displacement2D
с X и Y как двойной ... до тех пор, пока я не добавил свойство Length
в Vector2D ... и позже, Distance
в Displacement2D ..:/
Свойство (перечисление), определяющее тип объекта. То же самое: в том или ином месте, для удобства использования, вы можете указать , возможно, добавить участников в один из классов, который не имеет ничего общего с другими.:/Это делает ваши объекты либо неспособными расти/развиваться, либо странно с неиспользуемыми/поддельными членами ...
Так что, в конце концов, я думаю, вам придется выбирать между «замерзанием» ваших классов на их текущие состояние (участники) или запись каждого требуемой обработки преобразования кода и обновление тех случаев, когда это необходимо (добавление/редактирование элемента)
насчета Widening с CType?
Public Class StopWatch
Inherits TimeRecord
' ...
Public Shared Widening Operator CType(ByVal HistoricInstance As Historic) As StopWatch
Dim NewStopWatch As StopWatch
If HistoricInstance IsNot Nothing Then
NewStopWatch = New StopWatch(...)
' Set NewStopWatch Properties here...
' ...
Return NewStopWatch
Else
Return Nothing
End If
End Operator
End Class
И:
Public Class Historic
Inherits TimeRecord
' ...
Public Shared Widening Operator CType(ByVal StopWatchInstance As StopWatch) As Historic
Dim NewHistoric As Historic
If StopWatchInstance IsNot Nothing Then
NewHistoric = New Historic(...)
' Set NewHistoric Properties here...
' ...
Return NewHistoric
Else
Return Nothing
End If
End Operator
End Class
Примечание: При добавлении свойства в StopWatch, но не исторический, оператор Секундомер CType становится Сужение один вместо Widening.
Конечно, это создаст новый экземпляр класса каждый раз, когда вы будете класть один класс другому. Иногда это не удобно, если вы хотите, чтобы оба класса использовали один и тот же содержащийся объект (а не новый экземпляр) и месяцы позже вы забыли, что вы закодировали расширение оператора таким образом, чтобы создать новые экземпляры всех членов ...
Предположим, что у вас есть класс MyStopWatch типа StopWatch и свойство InitializationDateTime, которое установлено в Date . Теперь в конструкторе ..
MyStopWatch = New StopWatch() ' .InitializationDateTime = Date.Now
' do some stuff...
MyHistoric = CType(MyStopWatch, Historic) ' where MyHistoric.InitializationDateTime = Date.Now
С вышеуказанным кодом у вас будут различные значения свойства Initializ ationDateTime, даже если вы предполагаете, что правильно выбрали MyTimeRecord для MyHistoric, это связано с тем, что CType создал экземпляр Historic на позже, чем когда инициализирован MyTimeRecord.
Итак, как? Сериализация, свойство TypeCode/Enum или расширение CType?
Plutonix есть еще один способ:
Public Class StopWatch()
Public Sub New(ByVal HistoricInstance As Historic)
' Copy Properties values here...
End Sub
End Class
' Do the same for Historic Class.
Или вы можете также сделать функции (VB.net смысл)
Public Class StopWatch()
Public Function ToHistoric() As Historic
Dim NewHistoric As New Historic()
' .. set NewHistoric Properties values here
Return NewHistoric
End Function
End Class
Но результат тот же: вам придется писать код задайте значения свойств один за другим. Хорошая вещь: вы пишете код один раз, в конечном итоге обновляете его, но можете использовать его в любое время только с одной строкой кода ...
DirectCast
удобен, но подвержен краху во время выполнения.
TryCast
смешно, но вам все равно придется проверять провал кастинга. :/
Есть еще другие способы сделать это, но с этого времени один из предложенных способов достаточно полезен или у вас есть определенные требования, например, проблема выше?
, если они идентичны, то почему бы не просто 'TypeCode' свойство, чтобы отличить одно от другого? Тогда преобразование было бы просто вопросом изменения кода. В противном случае перегрузка ctor, которая принимает другой тип, позволит вам создать один из другого. – Plutonix
@ Jowijaro: добавьте пример кода на ваш вопрос !!! – umlcat