С# присвоить ссылку
Можно ли присвоить ссылку? Я знаю, что ref должен использоваться в методах.
string A = "abc";
string B = A;
B = "abcd";
Console.WriteLine(A); // abc
Console.WriteLine(B); // abcd
Можно ли что-то сделать
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
Ответы
Ответ 1
Вы не изменяете ссылку на A. Вы создаете целую новую строку. По-прежнему отображается "abc", потому что он не может быть изменен путем изменения B. После изменения B он указывает на целый новый объект. Строки тоже неизменяемы, поэтому любое изменение на один создает новую строку.
Чтобы еще раз ответить на ваш вопрос с помощью неизменяемых ссылочных типов, можно изменить свойства объекта, на который указывает переменная, и он покажет измененный эффект при доступе к другим переменным, указывающим на один и тот же объект. Это не означает, однако, что вы можете иметь переменную точку для совершенно нового объекта и иметь другие переменные (указывающие на старый объект), указывая на этот новый объект автоматически, не изменяя их.
Ответ 2
Как это работает. Строки являются ссылочным типом: ваша переменная A является ссылкой (например, указателем) на строку в куче, и вы просто копируете значение указателя (адрес строки) в переменную B.
Ваш пример не изменяет значение A, когда вы назначаете "abcd" в B, потому что строки обрабатываются специально в .net. Они неизменны, как указывает Кевин, но важно также отметить, что они имеют семантику типа значения, то есть назначения всегда приводят к ссылке, указывающей на новую строку, и не меняют значение существующей строки, хранящейся в переменная.
Если вместо строк вы использовали (например) автомобили и изменили свойство, вы увидите, что это так:
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" };
Возможно, стоит отметить, что он не работает таким образом для типов значений (целые числа, парные, float, longs, decimals, booleans, structs и т.д.). Они копируются по значению, если только они не помечены как Object
.
Ответ 3
Строки неизменны, что верно. Однако вы можете решить свою проблему, инкапсулируя строку внутри класса и создавая экземпляры A и B этого класса. Тогда A = B должен работать.
Ответ 4
Строки уже являются ссылками, после B = A, тогда B.equals(A) вернет true. Однако, когда вы делаете B = "abcd", вы делаете одно и то же, вы назначаете B ссылке на строковый литерал.
То, что вы хотите сделать, это изменить данные, на которые указывает строка, однако, поскольку строки в .NET являются неизменными, нет никакого способа сделать это.
Ответ 5
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
Ответ 6
Строки - это специальные объекты в С#, потому что они неизменяемы, иначе это будет ссылка. Вы можете запустить этот фрагмент, чтобы увидеть.
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