example - clone object c#
¿Por qué String.Clone() devuelve la cadena original y no una copia de ella? (3)
¿Cómo podrías detectar la diferencia? Solo comparando las dos referencias usando object.ReferenceEquals
. Pero por cualquier operación semántica en la cadena no puedes notar la diferencia.
La comparación de cadenas por referencia es casi siempre un error, ya que rara vez se puede confiar en que las prácticas se realicen o no.
Este problema no solo se aplica a String
. Si tuviera una clase de Point
inmutable, ¿por qué devolvería un objeto nuevo de Clone
? No hay necesidad.
IClonable
rara vez se usa y rara vez es útil, de todos modos. Si desea exponer a los usuarios de su clase de una manera para obtener una copia de una instancia determinada, no necesita heredar de IClonable
.
Sorprendentemente, String.Clone()
no devuelve una copia de una cadena como String.Copy()
haría. En su lugar, devuelve ''this''
, la cadena original.
Me gustaría entender por qué el equipo de .Net Framework elige ir de esta manera.
Según MSDN :
La interfaz ICloneable [...] requiere que su implementación del método Clone devuelva una copia de la instancia de objeto actual.
String.Clone()
claramente no sigue esta guía.
Sé que las cadenas son inmutables, pero si la razón es la inmutabilidad aquí, String.Copy()
también devolvería this
pero no lo hace.
Esta es una pregunta más bien teórica, por supuesto.
Como se ha mencionado, como las cadenas son de solo lectura, Clone () se comporta de manera razonable. Casi nunca necesita realmente dos instancias separadas de la cadena, y al no hacer una copia, se guarda la memoria. En el muy raro caso de que realmente necesite una copia (por alguna razón, quiere que Object.ReferenceEquals
devuelva false
), puede usar String.Copy()
lugar.
Puede parecer inútil tener un método que simplemente devuelva this
. La razón para tener tal método es implementar ICloneable
, y estoy de acuerdo en que String
debe implementar ICloneable
para que el código genérico como
T Foo<T>(T x, ...) where T:ICloneable {/* code that might clone x*/}
Puede ser compatible con String.
Sin embargo, para mí es un poco extraño que el método sea public
, ya que no hay razón para llamarlo directamente. Tendría sentido si solo fuera accesible a través de una referencia a ICloneable
.
IClonable está algo desaprobado, ya que no está claro qué significa "clonar" desde un punto de vista de todo el sistema (profundo, superficial ...). Ver http://blogs.msdn.com/b/brada/archive/2003/04/09/49935.aspx
La fuente de referencia documenta el método de clonación con el siguiente comentario:
// No tiene sentido clonar una cadena ya que son inmutables, así que simplemente devolvemos esto.
El internado de cadenas significa que es difícil recopilar cadenas (se puede hacer referencia a ellas más de una vez), lo que significa que realmente hacer una nueva copia de cadena solo sirve para acentuar el sistema. Además, el internado y la copia entran en conflicto entre sí, por lo que la regla general de internado gana.