2019年5月24日 星期五

[.Net] 如何複製instance(deep clone)/Prototype Pattern(原型模式)

前言:
有時候需要將物件instance複製出來,
.Net有提供ICloneable介面,以實作複製的方法(實作Clone方法):




而object有提供一擴充方法MemberwiseClone,以執行淺層複製(shallow copy),
但通常要的不是淺層複製,因reference type會指向同一塊heap,
因此若需要完全獨立的instance,就要自己實作。


作法:
1. 自行回傳新建立的instance:
若物件屬性可在建構子就完全決定的話,直接回傳新的instance即可:



不過通常沒這麼簡單,因此可先呼叫MemberwiseClone得到淺層複製,
再自行建立其他reference type屬性的instance:



不過如果物件屬性很多、很複雜又很多層,可考慮下一個做法。

2. 使用Json的Serialize與Deserialize:



不過作法2的執行時間應該比作法1長?? 實際測試一下:


各執行5次,作法2執行時間都在7秒上下,而作法1只要140毫秒,
因此2種作法各有所長,看狀況使用了。


參考資料:
https://docs.microsoft.com/zh-tw/dotnet/api/system.icloneable?view=netframework-4.8
https://docs.microsoft.com/zh-tw/dotnet/api/system.object.memberwiseclone?view=netframework-4.8#System_Object_MemberwiseClone
https://stackoverflow.com/questions/78536/deep-cloning-objects