2012-06-16 41 views
4
string name = "bob"; 
object obj = name; 
obj = "joe"; 
Console.WriteLine(name); 

我对名字的打印方式有些困惑。如果字符串和对象都是引用类型,它们不应该在“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 

当两者都是类引用时会发生什么?为什么它不会以同样的方式工作,因为我可以通过一个引用更改一个类字段,并将其反映在另一个引用中。类变量也应该是引用。那是不可改变的伤疤吗?

+0

你有一个C++的背景? – Marlon

+0

我很久以前做过。我想那是我感到困惑的地方? – user943870

+0

@ user943870也许 - 很多C++人看到“引用”,认为“引用类型”的含义类似于C++引用,但它有很大的不同。 –

回答

6

不应它们指向堆上的同一块内存的“OBJ =名”分配

是后。它们都引用相同的字符串实例。只要你做

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

然而,:您可以通过调用看到这个

obj = "joe"; 

你改变这一点,以便obj现在引用不同的字符串。 name仍然会引用原始字符串,但是,因为您尚未重新分配它。

如果然后做:

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

这将是在这一点虚假。

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" 
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指向的对象。

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" 
+0

非常好的例子来说明OP的困惑。 –

相关问题