Why does String.Clone() returns the original string and not a copy of it?

后端 未结 3 1387
轻奢々
轻奢々 2021-02-18 17:40

Surprisingly, String.Clone() doesn\'t return a copy of a string as String.Copy() would do. Instead, it returns \'this\', the original stri

相关标签:
3条回答
  • 2021-02-18 18:18

    How could you detect the difference? Only by comparing the two references using object.ReferenceEquals. But by any semantic operation on the string you can't tell the difference.

    Comparing strings by reference is almost always a bug to begin with because you can rarely rely on interning to happen or not happen.

    This issue does not only apply to String. If you had an immutable Point class, why would you return a fresh object from Clone? No need.

    IClonable is rarely used and rarely useful, anyway. If you want to expose users of your class a way to obtain a copy of a given instance you don't need to inherit from IClonable at all.

    0 讨论(0)
  • 2021-02-18 18:19

    IClonable is somewhat deprecated as it's unclear what "Clone" means from a system-wide standpoint (deep, shallow...). See http://blogs.msdn.com/b/brada/archive/2003/04/09/49935.aspx

    The reference source documents the Clone method with the following comment:

    // There's no point in cloning a string since they're immutable, so we simply return this.

    Interning of strings means that it's hard to collect strings (they can be referenced more than once) which means really making a new copy of string serves only to stress the system. Plus, interning and copying conflict with each other--so the general rule of interning wins.

    0 讨论(0)
  • 2021-02-18 18:38

    As has been mentioned, since strings are read-only, Clone() behaves reasonably. You virtually never actually need two separate instances of the string, and by not making a copy, memory is saved. In the very rare case that you actually need a copy (for some reason you want Object.ReferenceEquals to return false), you can use String.Copy() instead.

    It may seem pointless to have a method that just returns this. The reason to have such a method is to implement ICloneable, and I agree that String should implement ICloneable so that generic code like

    T Foo<T>(T x, ...) where T:ICloneable {/* code that might clone x*/}
    

    can be compatible with String.

    It's a little strange to me that the method is public, though, since there's no reason to call it directly. It would make sense if it were only accessible through a reference to ICloneable.

    0 讨论(0)
提交回复
热议问题