Aquí es una buena manera de pensar en el diferencia entre los tipos de valores, pasar por valor, tipos de referencia y pasar por referencia:
Una variable es un contenedor.
Una variable de tipo valor contiene una instancia. Una variable de tipo de referencia contiene un puntero a una instancia almacenada en otro lugar.
Al modificar una variable de tipo valor, se muta la instancia que contiene. La modificación de una variable de tipo de referencia muta la instancia a la que apunta.
Las variables de tipo de referencia separadas pueden apuntar a la misma instancia. Por lo tanto, la misma instancia puede mutarse a través de cualquier variable que lo señale.
Un argumento pasado por valor es un contenedor nuevo con una nueva copia del contenido. Un argumento pasado por referencia es el contenedor original con su contenido original.
Cuando un argumento de valor-tipo se pasa por valor: La reasignación del contenido del argumento no tiene ningún efecto fuera del alcance, porque el contenedor es único. La modificación del argumento no tiene ningún efecto fuera del alcance, porque la instancia es una copia independiente.
Cuando un argumento de tipo de referencia pasa por valor: La reasignación del contenido del argumento no tiene ningún efecto fuera del alcance, porque el contenedor es único. La modificación del contenido del argumento afecta al ámbito externo, ya que el puntero copiado apunta a una instancia compartida.
Cuando se pasa cualquier argumento por referencia: La reasignación del contenido del argumento afecta al ámbito externo, porque el contenedor se comparte. La modificación del contenido del argumento afecta el alcance externo, porque el contenido se comparte.
En conclusión:
una variable de cadena es una variable de tipo de referencia. Por lo tanto, contiene un puntero a una instancia almacenada en otro lugar. Cuando pasa por valor, su puntero se copia, por lo que modificar un argumento de cadena debería afectar a la instancia compartida. Sin embargo, una instancia de cadena no tiene propiedades mutables, por lo que un argumento de cadena no se puede modificar de todos modos. Cuando se pasa por referencia, el contenedor del puntero se comparte, por lo que la reasignación seguirá afectando al alcance externo.
Ver el artículo mencionado por Jon a continuación. El comportamiento que mencionas puede ser reproducido por punteros C++ también. – Sesh
Muy buena explicación en [MSDN] (http://msdn.microsoft.com/en-us/library/s6938f28.aspx) también. –
Posible duplicado de [En C#, ¿por qué String es un tipo de referencia que se comporta como un tipo de valor?] (Http://stackoverflow.com/questions/636932/in-c-why-is-string-a-reference-type -that-behaves-like-a-value-type) – Liam