2012-03-20 7 views
11

¿Es posible asignar por referencia? Sé que ref se debe usar en métodos.C# asignar por referencia

string A = "abc"; 
string B = A; 
B = "abcd"; 
Console.WriteLine(A); // abc 
Console.WriteLine(B); // abcd 

¿Puedo tener algún tipo de

string A = "abc"; 
string B = (ref)A; 
B = "abcd"; // A was assigned to B as reference, so changing B is the same as changing A 
Console.WriteLine(A); // abcd 
Console.WriteLine(B); // abcd 
+0

posible duplicado de http://stackoverflow.com/questions/1219664/c-sharp-reference-type-assignment-vs-value-type-assignment –

+1

@Tudor Creo que está esperando el valor de " abcd "para ser asignado a A. –

+0

@Chris Sí, soy – Marin

Respuesta

7

No está modificando la referencia a A. Están creando una cadena totalmente nueva. A todavía muestra "abc", porque no puede modificarse modificando B. Una vez que modifica B, apunta a un objeto completamente nuevo. Las cadenas también son inmutables, por lo que cualquier cambio en una crea una nueva cadena.

Para responder mejor su pregunta con tipos de referencia no inmutables, es posible modificar las propiedades de un objeto al que apunta una variable y mostrará el efecto modificado cuando acceda a otras variables que apuntan al mismo objeto. Sin embargo, esto no significa que puede tener un punto variable para un objeto completamente nuevo, y tener otras variables (que apuntan al objeto viejo) apuntan a ese nuevo objeto automáticamente sin modificarlos también.

+0

Eso no es verdad.solo está cambiando la referencia de la variable 'B'. Sería lo mismo si b fuera del tipo 'List '. – gdoron

+0

Sí, lo escribí demasiado rápido. Creo que eso lo aclara un poco. – kemiller2002

7

Así es como funciona. Las cadenas son un tipo de referencia: su variable A es una referencia (como un puntero) a una cadena en el montón, y usted está copiando el valor del puntero (la dirección de la cadena) en la variable B.

Su ejemplo no cambia el valor de A cuando asigna "abcd" a B porque las cadenas se tratan especialmente en .net. Son inmutables, como señala Kevin, pero también es importante tener en cuenta que tienen semántica de tipo de valor, es decir, las asignaciones siempre dan como resultado que la referencia apunte a una nueva cadena, y no cambia el valor de la cadena existente almacenada en La variable.

Si, en lugar de cadenas, que utiliza (por ejemplo) los coches, y cambia una propiedad, que vería este es el caso:

public class Car { 
    public String Color { get; set; } 
} 

Car A = new Car { Color = "Red" }; 
Car B = A; 
B.Color = "Blue"; 
Console.WriteLine(A.Color); // Prints "Blue" 

// What you are doing with the strings in your example is the equivalent of: 
Car C = A; 
C = new Car { Color = "Black" }; 

Es probablemente la pena señalar que no funciona de esta manera para tipos de valores (enteros, dobles, flotantes, largos, decimales, booleanos, estructuras, etc.). Esos se copian por valor, a menos que estén enmarcados como Object.

2

Las cadenas ya son referencias, después de B = A, entonces B.equals (A) devolverá verdadero. Sin embargo, cuando haces B = "abcd" estás haciendo lo mismo , estás asignando B a una referencia al literal de la cadena.

Lo que quieres hacer es modificar los datos apuntados por la cadena, sin embargo, como las cadenas en .NET son inmutables, no hay forma de hacerlo.

2
public class ReferenceContainer<T> 
{ 
    public T Value {get;set;} 
    public ReferenceContainer(T item) 
    { 
     Value = item; 
    } 

    public override string ToString() 
    { 
     return Value.ToString(); 
    } 

    public static implicit operator T (ReferenceContainer<T> item) 
    { 
     return Value; 
    } 
} 

var A = new ReferenceContainer<string>("abc"); 
var B = A; 
B.Value = "abcd"; 
Console.WriteLine(A);//abcb 
Console.WriteLine(B);//abcd 
4

Las cadenas son inmutables, eso es cierto. Sin embargo, puede resolver su problema encapsulando cadenas dentro de una clase y realizando instancias A y B de esa clase. Entonces A = B debería funcionar.

+0

+1, para la solución alternativa. Tan sencillo como eso. – nawfal

0

Las cadenas son objetos especiales en C# porque son inmutables, de lo contrario sería por referencia. Puede ejecutar este fragmento para ver.

public class Foo 
{ 
    public string strA; 
} 

Foo A = new Foo() { strA = "abc" }; 
Foo B = A; 

B.strA = "abcd";    

Console.WriteLine(A.strA);// abcd 
Console.WriteLine(B.strA);//abcd 
Cuestiones relacionadas