2010-10-01 40 views
1

我有一些困惑與引用類型下面是測試例子 請告訴我它是如何工作的C#引用類型的行爲

class TestClass 
{ 
    public int i = 100; 
} 

class MyTestClass 
{ 
    public void Method() 
    { 
     int i = 200; 
     var testClass = new TestClass(); 
     testClass.i = 300; 
     Another(testClass, i); 
     Console.WriteLine("Method 1:" + testClass.i); 
     Console.WriteLine("Method 2:" + i); 
    } 
    public void Another(TestClass testClass, int i) 
    { 
     i = 400; 
     testClass.i = 500; 
     testClass = new TestClass(); 
     //If we have set here again testClass.i = 600; what should be out putin this case 
     Console.WriteLine("Another 1:" + testClass.i); 
     Console.WriteLine("Another 2:" + i); 
    } 
    public static void Main() 
    { 
     MyTestClass test = new MyTestClass(); 
     test.Method(); 
     Console.ReadLine(); 
    } 
} 

** *編輯* ** * ** 應該輸出什麼,以及該對象的數量是多少倍tClass()將在執行期間創建。

回答

4

在C#中,任何一個結構都是一個值類型,任何一個類都是一個引用類型。將值類型作爲參數傳遞給另一個方法時,該方法無法更改原始值(除非使用ref關鍵字傳遞值類型)。當您將引用類型作爲參數傳遞給另一個方法方法時,該方法對該對象所做的任何更改都會在方法返回時反映到該對象中。輸出將是:

另一個1:100

另一個2:400

方法1:500

方法2:200

在另一種方法中的變量i不能改變Method方法中變量i的值,因爲我是一個值類型;因此,方法(200)中i的值不會因您對另一方的調用而改變。然而 識別TestClass是引用類型,所以另可在其內改變字段,因此在該行:500:

testClass.i = 500; 

通過方法如看到的那樣,方法1的因此輸出改變的值。當你在一行中分配一個TestClass的新實例時:

testClass = new TestClass();

你已經改變了引用的內容另一種方法,但Method中的原始實例不再可用於該方法另一個,因此另一個對其testClass變量做的任何操作都不會影響Method所引用的實例

5

輸出應爲:

 
Another 1:100 
Another 2:400 
Method 1:500 
Method 2:200 

C#經過值,除非使用了ref關鍵字。對於值類型,該值被複制。對於參考類型,複製參考文獻的值。

變量itestClass.i完全無關。我首先看一下這個簡單的例子,i是一個int - 一個值類型。當您將方法Anotheri作爲參數進行調用時,它將按值傳遞,以便在方法Another內修改i的值,但不會更改Method中的變量i的值 - 它始終等於200。

可變testClass的值也由值來傳遞,但在這種情況下,因爲它是一個引用類型的基準的值被傳遞,因此在Another可變testClass最初是指相同的對象中Method可變。當您在Another修改testClass.i值它改變了你在Method所以,它的成員設置爲300

創建的對象,然後該行創建了一個新的和無關的對象:

testClass = new TestClass(); 

有時它是更容易看到一個圖,其中頂行顯示的變量,並在最後一行會發生什麼表明他們參考的對象:

 
Before assignment:      After assignment: 

+-------------+ +-------------+  +-------------+ +-------------+ 
| Method  | | Another  |  | Method  | | Another  | 
| testClass | | testClass |  | testClass | | testClass | 
+-------------+ +-------------+  +-------------+ +-------------+ 
     |     |     |     | 
     |     |     |     | 
     v     |     v     v 
+-----------+   |    +-----------+  +-----------+ 
| TestClass |<-----------+    | TestClass |  | TestClass | 
| i = 300 |       | i = 300 |  | i = 100 | 
+-----------+       +-----------+  +-----------+ 

所以testClass.i時打印機的價值Another中的d是在構造函數中設置的默認值,即100。該賦值不會修改原始對象。你只是重新分配變量來指向別的東西。

+0

@Timwi:更新。現在好點了嗎? – 2010-10-01 21:22:08

+0

如果我在 之後設置了我的值testClass = new TestClass(); 另一個()方法中的testClass.i = 600,在這種情況下應該輸出什麼? – Vijjendra 2010-10-01 21:24:34

+0

@Vijjendra:哪個「我」?局部變量或testClass的成員? (PS:對於解釋的目的來說,將不同的變量稱爲不同的名稱是有用的,你有三種不同的東西,都稱爲「i」。) – 2010-10-01 21:26:44

0

基本上,

testClass.i = 500; 

改變對象內的值。你正在傳遞這個對象,所以這個改變會被所有對對象引用的東西看到。但是

i = 400; 
    testClass = new TestClass(); 

這些賦值只會改變本地參數的值。在同一方法之外的任何代碼都看不到此更改。