是等号通过引用还是对象副本?

时间:2013-02-13 10:10:04

标签: c# string object reference

当我有这段代码时:

class A 
{
    public int X = 0;
 ...
}

public void Function()
{
    // here I create a new instance of class
    A a = new A();
    a.X = 10;
    // here I create a pointer to null
    A b = null;
    // here I assign a to b
    b = a;
    b.X = 20;
}

我现在将引用传递给了A类的实例吗?或者我将A的实例克隆到新实例并在b?

中创建了对它的引用

正在改变b中的X也改变了?为什么?如果没有,创建a的副本并将其插入b的正确方法是什么?

为什么字符串相同会始终创建副本?是否在字符串中覆盖了相等的运算符?

string a = "hello";
string b = a;
b = "world";
// "hello world"
Console.WriteLine( a + " " + b );

4 个答案:

答案 0 :(得分:6)

C#使用引用而不是指针。课程是reference types

在您的示例中,ba具有相同的引用。它们引用内存上的相同位置。

  

改变b中的X也改变了?为什么呢?

是的,因为它们引用相同的对象并且更改一个引用会影响另一个引用。

string a = "hello";
string b = a;
b = "world";
// "hello world"
Console.WriteLine( a + " " + b );

字符串也是引用类型。但他们也是immutable type。这意味着你无法改变它们。即使你认为你改变它们,你实际上也会创建新的字符串对象。

  1. 您创建的对象包含"hello",其中包含名为a的引用。
  2. 一行,您创建一个名为b的新引用,引用同一个对象。 ("hello"
  3. 为您分配名为b的{​​{1}}参考新对象。您的参与不再引用"world"对象了。

答案 1 :(得分:4)

  

我现在将指针传递给A类的实例吗?或者我克隆了   A实例到新实例并在b?

中创建了一个指向它的指针

ba 保持相同的引用,两者都指向同一位置。

  

改变b中的X也改变了?为什么呢?

因为它们都指向相同的引用。

  

创建a的副本并将其插入b的正确方法是什么?

实施IClonable interface

  

支持克隆,用于创建类的新实例   与现有实例相同的值

修改

由于您使用字符串编辑了问题,尽管字符串是引用类型,但它们也是immutable

string (C# Reference)

  

字符串是不可变的 - 字符串对象的内容不能   在创建对象后更改,尽管语法可以实现   好像你可以这样做。

答案 2 :(得分:1)

对象b指向对象a,您必须使用IClonable接口进行深度克隆以进行复制。

答案 3 :(得分:1)

分配时,传递指定表达式的返回值的副本。

  • 对于值类型,这是您在使用它们时通常会看到的值(如整数的数值)。
  • 对于引用类型,实际值类似于指向引用对象的地址(但真正是什么,是实现细节)。因此,即使您传递了该地址的副本,该副本也会指向同一个对象。