对象引用 = 字符串引用; 改变一个不会影响另一个吗?

3
string name = "bob";
object obj = name; 
obj = "joe";
Console.WriteLine(name);

我对名称如何打印bob有点困惑。如果字符串和对象都是引用类型,那么在“obj = name”分配后,它们不应该指向堆上的同一块内存吗?感谢任何澄清。
编辑:StackUnderflow的示例提出了另一个相关问题。
MyClass myClass1 = new MyClass();
MyClass myClass2;
myClass1.value = 4;
myClass2 = myClass1;
myClass2.value = 5;  // myClass1 and myClass2 both have 5 for value

当两个都是类引用时会发生什么?为什么它不像我可以通过一个引用更改类字段并且在另一个引用中反映出来的方式一样工作。类变量也应该是引用。那么字符串是不可变的这一点起了作用吗?


你有C++的背景吗? - Marlon
我很久以前就做过了。我猜那就是我感到困惑的地方? - user943870
@user943870 可能很多C++程序员看到“引用”一词就会认为“引用类型”意味着类似于C++引用的东西,但实际上它们是非常不同的。 - Reed Copsey
我最开始使用的是C++,一直都只用它。我迟早会理解这个的。 - user943870
请查看“Stack Overflow不需要您的SEO技能”链接。 - John Saunders
4个回答

6

"obj = name"赋值后,它们不应该指向堆上相同的内存地址吗?

是的。它们都引用同一个字符串实例。您可以通过调用以下代码来验证:

bool sameStringReference = object.ReferenceEquals(obj, name); // Will be true

不过,一旦你这样做:

obj = "joe";

您正在更改此内容,使得obj现在引用不同的字符串。然而,由于您尚未重新分配,name仍将引用原始字符串。

如果您接下来执行:

sameStringReference = object.ReferenceEquals(obj, name); // Will be false

此时此刻这将是错误的。

5

(由于OP提到了C++背景):

C#中的引用与C ++中的引用不同,它们的作用有点像指针。在C#中,它们在初始化时不是“绑定”的,因此赋值运算符(=将分配一个新引用而不是修改原始对象

在C ++中:

std::string name = "bob";
std::string& obj = name; // now bound to 'name'
obj = "joe"; // name is directly affected
std::cout << name; // prints "joe"

在C#中:

string name = "bob";
string obj = name; // both reference "bob"
obj = "joe"; // obj now references "joe", and name still references "bob"
Console.WriteLine(name); // prints "bob"

非常好的例子,可以说明原帖作者的困惑。 - Kirk Woll

1

赋值和对变量进行操作之间存在差异。如果您有以下内容:

public class A { public string Name; }

...
var orig = new A { Name = "bob" };
var obj = orig;
obj.Name = "joe";
Console.WriteLine(orig.Name); //"joe"

在这里,您将修改指向的对象 obj (而不是修改 obj 指向的内容)。


1

不行,你只是把obj的引用重新分配给“joe”字符串对象。 字符串是不可变的,所以不能通过这种方式更改它们。 最好的方法是用自己的类包装name

public class MyName
{
    public string Name { get; set; }
}

MyName firstName = new MyName() { Name = "bob" };
MyName secondName = name;
secondName.Name = "joe";
Console.WriteLine(firstName.Name) //outputs "joe"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接