Reputation: 12920
Is it possible to assign by reference? I know that ref has to be used in methods.
string A = "abc";
string B = A;
B = "abcd";
Console.WriteLine(A); // abc
Console.WriteLine(B); // abcd
Can I have some sort of
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
Upvotes: 25
Views: 37612
Reputation: 21
All you do is this:
string A = "abc";
ref 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
Upvotes: 2
Reputation: 416149
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>("X");
var B = A;
B.Value = "Y";
Console.WriteLine(A);// ----> Y
Console.WriteLine(B);// ----> Y
Upvotes: 4
Reputation: 3915
Strings are special objects in C# because they are immutable, otherwise it would be by reference. You can run this snippet to see.
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
Upvotes: 2
Reputation: 12261
Strings are immutable that's true. However you can resolve your issue by encapsulating string within a class and making A and B instances of that class. Then A = B should work.
Upvotes: 5
Reputation: 115548
You aren't modifying the reference to A. You are creating a whole new string. A still shows "abc", because it can't be changed by modifying B. Once you modify B, it points to a whole new object. Strings are immutable too, so any change to one creates a new string.
To further answer your question with non-immutable reference types, it is possible to modify the properties of an object that a variable points to and it will show the changed effect when you access other variables pointing to the same object. This does not mean however that you can have a variable point to a brand new object, and have other variables (that pointed to the old object) point to that new object automatically without modifying them as well.
Upvotes: 11
Reputation: 51344
That's how it works already. Strings are a reference type- your variable A is a reference (like a pointer) to a string on the heap, and you are just copying the pointer's value (the address of the string) into the variable B.
Your example doesn't change the value of A when you assign "abcd" to B because strings are treated specially in .net. They are immutable, as Kevin points out- but it is also important to note that they have value type semantics, that is assignments always result in the reference pointing to a new string, and doesn't change the value of the existing string stored in the variable.
If, instead of Strings, you used (for example) cars, and changed a property, you'd see this is the case:
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" };
It's probably worth noting that it does not work this way for value types (integers, doubles, floats, longs, decimals, booleans, structs, etc). Those are copied by value, unless they are boxed as an Object
.
Upvotes: 27
Reputation: 42317
Strings are already references, after B = A then B.equals(A) will return true. However, when you do B = "abcd" you're doing the same thing, you're assigning B to a reference to the string literal.
What you are wanting to do is modify the data pointed to by the string, however, because Strings in .NET are immutable there is no way to do that.
Upvotes: 2