C#通过引用分配

时间:2012-03-20 18:28:53

标签: c#

是否可以通过引用分配?我知道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

7 个答案:

答案 0 :(得分:13)

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

值得注意的是,它对于值类型(整数,双精度,浮点数,长整数,小数,布尔值,结构等)不起作用。这些是按值复制的,除非它们被装箱为Object

答案 1 :(得分:8)

您没有修改对A的引用。您正在创建一个全新的字符串。 A仍显示“abc”,因为它无法通过修改B来更改。一旦修改B,它就指向一个全新的对象。字符串也是不可变的,因此对一个字符串的任何更改都会创建一个新字符串。

要使用非不可变引用类型进一步回答您的问题,可以修改变量指向的对象的属性,并在访问指向同一对象的其他变量时显示更改的效果。然而,这并不意味着您可以将变量指向一个全新的对象,并让其他变量(指向旧对象)自动指向该新对象,而不会修改它们。

答案 2 :(得分:4)

字符串是不可变的,这是真的。但是,您可以通过将字符串封装在类中并创建该类的A和B实例来解决您的问题。然后A = B应该有效。

答案 3 :(得分:2)

字符串已经引用,在B = A之后,B.equals(A)将返回true。但是,当您执行B =“abcd”时,您正在执行相同的操作,您将B分配给对字符串文字的引用。

你想要做的是修改字符串指向的数据,但是,因为.NET中的字符串是不可变的,所以没有办法做到这一点。

答案 4 :(得分: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>("X");
var B = A;
B.Value = "Y";
Console.WriteLine(A);// ----> Y
Console.WriteLine(B);// ----> Y

答案 5 :(得分:1)

字符串是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

答案 6 :(得分:0)

你要做的就是:

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