Why is MemberwiseClone defined in System.Object protected?

前端 未结 4 457
礼貌的吻别
礼貌的吻别 2020-12-18 21:42

I\'m wondering why MemberwiseClone is defined as protected. This means that only derived types can access it. What is the problem if it was defined as public?

4条回答
  •  误落风尘
    2020-12-18 22:22

    If MemberwiseClone didn't exist, there would be no means, other than by using Reflection, for any inheritable class to support a polymorphic cloning operation, except by requiring every derived class to explicitly provide one. Failure of a derived class to provide a cloning operation would result in unexpected behavior. For example, suppose Vehicle, Car, and ToyotaCar provide explicit cloning methods, but ToyotaCorolla does not. If someone has an object of type ToyotaCorolla and tries to clone it, the resulting object would be a ToyotaCar. Since there are situations where polymorphic cloning is required, and it would be inconvenient to require every derived class of a clonable class to provide explicit support, MemberwiseClone is a necessary part of the framework.

    On the other hand, MemberwiseClone can also be dangerous. Performing a MemberwiseClone on an object will frequently yield a broken object; attempting using any properties or methods of the broken object may corrupt the original.

    It's too bad Microsoft didn't better define a good practice for cloning. It's possible, and not overly difficult, to design a polymorphic cloning pattern which doesn't require inherited classes to explicitly do anything unless they add fields which require special handling, or unless a caller will expect the declared return type of the Clone method's to be the derived class. While the latter situation will frequently be a requirement, failure to explicitly implement the necessary method will yield a compile-time error, rather than buggy run-time behavior.

    BTW, Microsoft seems to think there's something confusing about deep vs. shallow cloning. There isn't. Calling "Clone" on an object should clone the object to whatever depth is necessary to obtain its defined semantics. Cloning a FileCabinet(Of T) should yield a new FileCabinet which is, for purposes of the methods of FileCabinet, independent of the original, but it should hold the same instances of T as the original. Since the purpose of a file cabinet is to hold instances of T, but not to do anything with them, cloning the cabinet should not imply cloning the contents (but it would imply cloning any arrays which the Cabinet itself uses to hold the contents).

    BTW, if I had my druthers there would be an interface in .Net, implemented by String and primitive types (plus many others), called DeepClonableIfMutable. When applied to a String or other primitive, the DeepCloneIfMutable method would simply return the original object. User-defined immutable objects could implement DeepClonableIfMutableto behave similarly, while mutable objects would deep-clone themselves and any nested DeepClonableIfMutable instances.

提交回复
热议问题