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

C#通过引用赋值

这就是它的工作原理。字符串是一种引用类型-变量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