[vb.net] class에 대한 clone의 구현
class는 레퍼런스 타입인데 여기에 ICloneable의 Clone메서드를 구현하여 class의 내부값들을 그대로 복제할 수 있는 기능을 구현한다. 레퍼런스 타입은 하나의 메모리를 가리키고 있으므로 특정 인스턴스 값을 변경하면 다른 인스턴스의 값도 변경된다. 이를 극복하기 위하여 Clone 을 사용한다.
MemberwiseClone 메소드는 모든 value 타입 필드의 값을 그대로 복제하고 참조 타입인 경우는 참조로서 복제한다. 따라서 클래스 내부에 참조 타입 필드는 새로 생성하여 값을 옮겨 넣는 과정이 필요하다(shopping 클래스의 clone메서드와 order클래스의 clone메서드의 차이)
-- order.vb --
Imports System
Imports System.Text
Imports System.Collections.Generic
Public Class Order
Implements ICloneable
Public OrderNumber As String
Public PONumber As String
Public ShippingAddress As String
Public Sub New(ByVal _OrderNumber As String, ByVal _PONumber As String, ByVal _ShippingAddress As String)
OrderNumber = _OrderNumber
PONumber = _PONumber
ShippingAddress = _ShippingAddress
End Sub
' create a clone
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone
End Function
Public Overrides Function ToString() As String
Return String.Format("Order Number is {0}, and PO number is {1}", OrderNumber, PONumber)
End Function
End Class
-- shopping.vb --
Imports System
Imports System.Text
Imports System.Collections.Generic
Public Class Shopping
Implements ICloneable
Public Orders As New List(Of Order)
Public Sub New()
End Sub
Public Overrides Function ToString() As String
Dim str As New StringBuilder
For Each e As Order In Orders
str.AppendLine(String.Format("order{0}", e.OrderNumber))
Next
Return str.ToString
End Function
Public Function Clone() As Object Implements System.ICloneable.Clone
Dim newShopping As New Shopping
For Each e As Order In Me.Orders
newShopping.Orders.Add(DirectCast(e.Clone, Order))
Next
Return newShopping
End Function
End Class
-- module 1 --
Module Module1
Sub Main()
Dim originalShopping As New Shopping
originalShopping.Orders.Add(New Order("0001", "P001", "address1"))
originalShopping.Orders.Add(New Order("0002", "P002", "address2"))
originalShopping.Orders.Add(New Order("0003", "P003", "address3"))
Dim clonedShopping As Shopping = DirectCast(originalShopping.Clone, Shopping)
originalShopping.Orders(0).OrderNumber = "0005"
originalShopping.Orders(0).PONumber = "P005"
originalShopping.Orders(0).ShippingAddress = "address5"
Console.WriteLine(originalShopping.ToString)
Console.WriteLine(clonedShopping.ToString)
Console.ReadLine()
End Sub
End Module