ICloneable
Как было показано в разделе «MemberWiseClone», клонирование объекта, содержащего внутренние объекты, вызывает немало проблем. Разработчики .NET дают вам возможность сообщить о том, что данная возможность реализована в вашем классе. Для этой цели используется декларативный интерфейс ICloneable, состоящий из единственной функции Clone:
Public Interface ICloneable
Function Clone() As Object
End Interface
Этот интерфейс (а следовательно, и метод Clone) реализуется в том случае, если вы хотите предоставить пользователям своего класса средства для клонирования экземпляров. Далее вы сами выбираете фактическую реализацию метода Clone — не исключено, что она будет сводиться к простому вызову MemberWiseClone. Как было сказано выше, MemberWiseCl one нормально клонирует экземпляры, поля которых относятся к структурному типу или являются неизменяемыми (такие, как String). Например, в классе Empl oyee клонирование экземпляров может осуществляться методом Clone, поскольку все поля представляют собой либо строки, либо значения структурных типов. Таким образом, реализация IC1 опеаЫ е,для класса Empl oyee может выглядеть так:
Public Class Employee Implements ICloneable
Public Function Clone() As Object _
Implements ICloneable.Clone
Return CType(Me.MemberwiseClone, Employee)
End Function ' И т.д.
End Class
В классах, содержащих внутренние объекты, реализация метода Clone потребует значительно больших усилий (хотя в главе 9 описан прием, позволяющий достаточно просто решить эту задачу в большинстве случаев). Так, в приведенном выше классе EmbeddedObject необходимо клонировать внутренний массив, не ограничиваясь простым копированием.
Как это сделать? Очень просто. Поскольку класс Array реализует интерфейс ICloneable, он должен содержать метод для клонирования массивов. Остается лишь вызвать этот метод в нужном месте. Ниже приведена версия класса Ет-beddedObjects с реализацией ICloneabl e (ключевые строки выделены жирным шрифтом):
Public Class EmbeddedObjects Implements
ICloneable Private m_Ma() As String
Public Sub New(ByVal anArray() As String)
m_Data = anArray
End Sub
Public Function Clone() As Object Implements
ICloneable.Clone
Dim temp()As String
temp = m_Data.Clone ' Клонировать массив
Return New EmbeddedObjects(temp)
End Function
Public Sub DisplayData()
Dim temp As String
For Each temp In m_Data
Console.WriteLine(temp)
Next End
Sub Public
Sub ChangeDataCByVal
newData As String)
m_Data(0) = newData
End Sub
End Class
Список классов .NET Framework, реализующих интерфейс ШопеаЫе (а следовательно, поддерживающих метод Clone), приведен в описании интерфейса ШопеаЫе в электронной документации.