为什么 String.Clone() 返回原始字符串而不是它的副本



令人惊讶的是,String.Clone()不会像String.Copy()那样返回字符串的副本。相反,它返回 'this' ,原始字符串。

我想了解为什么.Net Framework团队选择这条路。

根据 MSDN:

ICloneable接口[...]要求你的实现 Clone 方法返回当前对象实例的副本。

String.Clone()显然没有遵循此准则。

我知道字符串是不可变的,但如果不可变性是这里的原因,String.Copy()也会返回this但它没有。

当然,这是一个相当理论化的问题。

你怎么能察觉到差异?只有通过使用object.ReferenceEquals比较两个参考文献。但是通过对字符串的任何语义操作,您都无法分辨出区别。

通过引用比较字符串几乎总是一个错误,因为您很少可以依靠实习来发生或不发生。

此问题不仅适用于String。如果你有一个不可变的Point类,你为什么要从Clone返回一个新对象?没必要。

无论如何,IClonable很少使用,也很少有用。如果要向类的用户公开一种获取给定实例副本的方法,则根本不需要从IClonable继承。

>IClonable有点不推荐使用,因为从系统范围的角度来看,"克隆"是什么意思(深,浅......)。请参阅 http://blogs.msdn.com/b/brada/archive/2003/04/09/49935.aspx

引用源记录了带有以下注释的克隆方法:

克隆字符串是没有意义的,因为它们是不可变的,所以我们只是返回这个。

字符串

的实习意味着很难收集字符串(它们可以被多次引用),这意味着真正制作字符串的新副本只会给系统带来压力。 另外,实习和复制是相互冲突的——所以实习的一般规则占了上风。

如前所述,由于字符串是只读的,Clone() 的行为是合理的。实际上,您实际上从不需要字符串的两个单独实例,并且通过不复制,可以节省内存。在极少数情况下,您实际上需要副本(出于某种原因您希望Object.ReferenceEquals返回false),您可以改用String.Copy()

拥有一个只返回 this 的方法似乎毫无意义。拥有这种方法的原因是实现ICloneable,我同意String应该实现ICloneable,以便通用代码像

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

可以与字符串兼容。

不过,这种方法public对我来说有点奇怪,因为没有理由直接调用它。如果只能通过引用ICloneable来访问它是有意义的。

相关内容

  • 没有找到相关文章

最新更新