2012-06-16 74 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的困惑。 –

相關問題