C#通过引用赋值
本文关键字:赋值 引用 | 更新日期: 2023-09-27 18:28:29
是否可以通过引用进行分配?我知道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
这就是它的工作原理。字符串是一种引用类型-变量a是对堆上字符串的引用(就像指针一样),您只是将指针的值(字符串的地址)复制到变量B中。
当你把"abcd"赋值给B时,你的例子不会改变A的值,因为字符串在.net中是特殊处理的。正如Kevin所指出的,它们是不可变的,但同样重要的是要注意,它们具有值类型语义,也就是说,赋值总是导致引用指向一个新字符串,而不会改变存储在变量中的现有字符串的值。
如果您使用(例如)汽车而不是字符串,并更改了一个属性,您会看到这种情况:
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" };
可能值得注意的是,它对值类型(整数、双精度、浮点、long、小数、布尔值、structs等)不起这种作用。这些都是按值复制的,除非它们被装箱为Object
。
您没有修改对A的引用。您正在创建一个全新的字符串。A仍然显示"abc",因为它不能通过修改B来更改。一旦修改B,它就会指向一个全新的对象。字符串也是不可变的,所以对一个字符串的任何更改都会创建一个新的字符串。
为了用非可变引用类型进一步回答您的问题,可以修改变量指向的对象的属性,当您访问指向同一对象的其他变量时,它将显示更改后的效果。然而,这并不意味着您可以让一个变量指向一个全新的对象,并让其他变量(指向旧对象)自动指向该新对象,而无需修改它们。
字符串是不可变的,这是真的。但是,您可以通过将字符串封装在类中并创建该类的a和B实例来解决问题。那么A=B应该起作用。
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
字符串已经是引用,在B=A之后,B.equals(A)将返回true。然而,当您执行B="abcd"时,您正在执行相同的操作,您将B分配给字符串文字的引用。
您想要做的是修改字符串所指向的数据,但是,由于.NET中的字符串是不可变的,因此无法做到这一点。
字符串是C#中的特殊对象,因为它们是不可变的,否则它将是引用的。您可以运行此代码段来查看。
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
您所做的就是:
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