3

我知道 .NET 中的 String 是 Object 的子类,而 .NET 中的 Objects 是引用类型。因此,下面的代码让我有点困惑。你能帮我理解其中的区别吗?谢谢

我声明了一个名为 MyInt 的类:

class MyInt
{
    int i;

    public int number
    {
        get { return i; }
        set { i = value; }
    }

    public override string ToString()
    {
        return Convert.ToString(i);
    }
}

然后是下面的代码:

MyInt a = new MyInt();
MyInt b = new MyInt();
a.number = 5;
b.number = 7;
b = a;
a.number = 9;

Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());

产量:

9  
9

我理解这是因为这是一个 Object = Reference Type ,所以 a 和 b 现在引用堆上的同一个对象。

但是这里会发生什么?

 string a1;
 string b1;
 a1 = "Hello";
 b1 = "Goodbye";
 b1 = a1;
 a1 = "Wazzup?";

 Console.WriteLine(a1);
 Console.WriteLine(b1);

这产生:

Wazzup?
Hello

String 是一个被区别对待的对象吗?

4

2 回答 2

6

首先,我们创建两个字符串变量。现在,它们没有引用任何内容,因为它们没有被初始化:

string a1;
string b1;

接下来,创建一个值为“Hello”的字符串,并返回对该内存空间的引用。 a1设置为该参考:

a1 = "Hello"; // a1 points to a place in memory with a string containing "Hello"

接下来,创建一个值为“Goodbye”的字符串,并设置 b1 以引用该字符串。

b1 = "Goodbye";

接下来我们做:

b1 = a1;

此分配将复制引用的值。现在,b1指向的字符串a1指向了,而“Goodbye”是无法到达的。由于字符串总是在堆上分配,垃圾收集器最终会停下来清理“再见”正在使用的内存,因为没有任何东西可以引用它了。*

*编辑:从技术上讲,这可能不是真的,因为字符串常量将被实习并因此被实习表根植 - 但我们只是说这些字符串来自数据库或其他东西。

接下来是一个值为“Wazzup?”的字符串。被创建,a1被设置为对它的引用:

a1 = "Wazzup?";

“Hello”字符串仍然被b1变量引用,所以它是安全的。考虑到所有这些:

// Prints "Wazzup" because we just set a1 to a reference to that string
Console.WriteLine(a1);

//Prints "Hello" because b1 still has its value it had copied over from a1
Console.WriteLine(b1);

希望这可以澄清事情。

于 2013-08-15T20:53:23.637 回答
0

请记住,更改 String 的值总是会创建 String 类的新实例。

例如

string test1 = "Test"; // point to memory address "1023"
test1 = "New test"; 
// Now new instance was created and variable point to another memory address
于 2013-08-15T21:07:45.740 回答