我想知道爲什麼MemberwiseClone被定義爲受保護的。這意味着只有派生類型可以訪問它。如果它被定義爲公共,那麼問題是什麼?爲什麼在System.Object中定義的MemberwiseClone受到保護?
回答
Pavel Minaev's answer from another discussion:
其他人已經解釋有關MemberwiseClone,但沒有人給它爲什麼被保護的解釋。我會盡力說明理由。
這裏的問題是MemberwiseClone只是盲目地複製狀態。在許多情況下,這是不可取的。例如,該對象可能有一個專用字段,它是對List的引用。一個淺的副本,比如MemberwiseClone會做什麼,會導致新的對象指向同一個列表 - 而這個類可能會被寫入,不會期望該列表與其他人共享。
或者一個對象可以有某種形式的ID字段,在構造函數中生成 - 再一次,當您克隆它時,會得到兩個具有相同ID的對象,這可能會導致方法中出現各種奇怪的失敗,獨特。
或者說您有一個打開套接字或文件流的對象,並存儲對該對象的引用。 MemberwiseClone只會複製引用 - 你可以想象,兩個對象試圖將調用交叉到同一個流不會結束。
簡而言之,對於任意對象,「克隆」不是一個明確定義的操作。成員運算符=在C++中默認爲所有類提供的事實更令人討厭,因爲人們經常忘記它在那裏,並且對於複製沒有意義的類或者是危險的類(而且有驚人的許多這樣的類)。
如果MemberwiseClone不存在,除了通過使用Reflection之外,對於任何可繼承的類來說,除了要求每個派生類明確提供一個以外,沒有任何方法支持多態克隆操作。派生類提供克隆操作失敗會導致意外的行爲。例如,假設Vehicle,Car和ToyotaCar提供了明確的克隆方法,但ToyotaCorolla沒有。如果某人有ToyotaCorolla類型的對象並試圖克隆它,則生成的對象將是ToyotaCar。由於存在需要多態克隆的情況,並且要求可克隆類的每個派生類提供明確的支持是不方便的,因此MemberwiseClone是該框架的必要部分。
另一方面,MemberwiseClone也可能是危險的。在對象上執行MemberwiseClone會頻繁產生一個破碎的對象;試圖使用破損對象的任何屬性或方法可能會破壞原始文件。
這太糟糕了微軟沒有更好地定義克隆的良好做法。設計一個多態克隆模式是可能的,不需要繼承類來明確地做任何事情,除非它們添加需要特殊處理的字段,或者除非調用者期望克隆方法的聲明返回類型是派生類。雖然後一種情況經常會成爲一種需求,但未明確實施必要的方法會產生編譯時錯誤,而不是錯誤的運行時行爲。
順便說一句,微軟似乎認爲有關深層克隆和淺層克隆有點混淆。沒有。在一個對象上調用「克隆」應該將對象克隆到任何深度,以獲得其定義的語義。克隆FileCabinet(Of T)應該產生一個新的FileCabinet,就FileCabinet的方法而言,它獨立於原始文件,但它應該與原始文件保持相同的T實例。由於文件櫃的目的是保存T的實例,但不對其做任何事情,克隆內閣不應該暗示克隆內容(但它意味着克隆內閣自己用來保存內容的任何陣列)。
順便說一句,如果我有我的dr drhers,那麼在.NET中會有一個接口,由String和原始類型(以及其他許多元素)實現,稱爲DeepClonableIfMutable。當應用於String或其他基元時,DeepCloneIfMutable方法將簡單地返回原始對象。用戶定義的不可變對象可以實現DeepClonableIfMutableto類似的行爲,而可變對象將深度克隆自己和任何嵌套的DeepClonableIfMutable實例。
- 很多東西沒有意義被克隆;任何會談非託管手柄,例如
- 大多數對象不需要克隆設施
- 深拷貝東西正確是真的硬,如果你去的幾個簡單的情況外
- 在許多情況下,還有比盲目克隆
- 更好的比喻手動添加克隆設施你的類型的需要是十分容易
對我來說,這是一個不費吹灰之力,這應該是不是被默認添加到公共API。
- 1. 對象類的受保護方法MemberWiseClone()
- 2. 爲什麼URLClassLoader.addURL在Java中受到保護?
- 3. 爲什麼對象類中的方法受到保護?
- 4. 爲什麼MVC中Controller類的TryUpdateModel受到保護?
- 5. 受保護設置在VB.Net中的接口定義的屬性
- 6. 爲什麼在Obejct類中有公共方法,它們可能受到保護?
- 7. Spring oauth2指定受保護和不受保護的資源
- 8. 爲什麼我不能在as3中將受保護的方法覆蓋爲public?
- 9. 爲什麼受保護訪問的Java規則是這樣的?
- 10. 爲什麼get_object_vars返回受保護的屬性?
- 11. 爲什麼這個受保護的屬性不起作用?
- 12. 爲什麼要保護CollectionView.CollectionChanged?
- 13. 爲什麼Typescript定義文件不能保護成員?
- 14. 清除受保護工作表中未受保護特定範圍的內容
- 15. 爲什麼我可以在後繼中公開受保護的方法?
- 16. 定義什麼Sortable接受?
- 17. 爲什麼警衛不能保護我免受我
- 18. 爲什麼BindingList <T> RemoveItem方法受保護
- 19. .NET中受保護的類
- 20. 爲什麼我得到受保護的頁面而不是登錄頁面?
- 21. 爲什麼像RedirectToAction()和HttpNotFound()這樣的Controller方法受到內部保護?
- 22. 爲什麼.htaccess受保護的目錄在http上工作,但不在https上?
- 23. 爲什麼Joda Time中的LocalTime的getLocalMillis()是受保護的方法?
- 24. 在不受保護和受保護的工作表中實現代碼VBA Excel
- 25. 「50289由於項目受到保護,無法執行操作」,但爲什麼?
- 26. 克隆受保護的邊緣受保護的驅動器
- 27. 爲什麼Spring AOP在某些情況下攔截受保護的方法?
- 28. 爲什麼在Heroku上運行的應用程序不受Heroku SSL保護
- 29. 覆蓋受保護的內部受保護!
- 30. 受保護與不受保護的區別