我想知道为什么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. 受保护与不受保护的区别