2013-10-01 46 views
4

以下代碼的輸出令我感到驚訝。我認爲「a」應該引用新創建的對象。有人可以解釋爲什麼結果不是2?c#對象通過引用傳遞或按值傳遞

class Program 
{ 
    static void Main(string[] args) 
    { 
     aclass a = new aclass(); 
     Process(a); 
     Console.WriteLine(a.number); 

     Console.ReadLine(); 
    } 

    static void Process(aclass a) 
    { 
     aclass temp = new aclass(); 
     temp.number++; 
     //Console.WriteLine(temp.number); 

     a = temp; 
     a.number++; 
     //Console.WriteLine(a.number); 
    } 

} 

class aclass 
{ 
    public int number = 0; 
} 

編輯:這是一個面試問題。我剛剛意識到我很長時間以來誤解了這個概念。參數a與原始a不同,儘管它們引用相同的地址。

+2

因爲當你做一個'= temp'你會被傳入的說法,哪些是你將要起便修改之間的脫節。如果你沒有這樣做,你會在'Main'中獲得'1'。 – Jon

+0

在c#中,參數值不是通過引用傳遞的,請查看[ref](http://msdn.microsoft.com/en-us/library/14akc2c7.aspx)關鍵字。 –

+1

你在'temp'上增加了'number'兩次,但是你沒有對'Main'中定義的'a'做任何工作。 – Sam

回答

10

你並沒有改變實際的原始引用,你只是改變參數中保持的引用,這個引用微妙地不一樣,所做的修改不會被保存回調用者。您可以使用outref來更改此行爲。

在這種情況下,特別是你想使用ref因爲你也順帶參考

嘗試:

class Program 
{ 
    static void Main(string[] args) 
    { 
     aclass a = new aclass(); 
     Process(ref a); 
     Console.WriteLine(a.number); 

     Console.ReadLine(); 
    } 

    static void Process(ref aclass a) 
    { 
     aclass temp = new aclass(); 
     temp.number++; 
     //Console.WriteLine(temp.number); 

     a = temp; 
     a.number++; 
     //Console.WriteLine(a.number); 
    } 

} 

記住你與a = temp分配一個全新的基準。如果你只是想更新你在最初傳遞現有的類,那麼你可以這樣做:

a.number = temp.number; 
a.number++; 

這將否定了ref的需要。

你可以閱讀更多的MSDN:

Passing Reference Type Parameters

ref Keyword

out Keyword

+0

這澄清了我對論點和原始對象的誤解。參數a與原始a不同,但最初引用的是相同的值。 – mortdale

0

此行aclass a = new aclass();創建一個變量(空間,我們可以存儲數據)在內存中。考慮到其在內存中的地址是*(0x12DF)並存儲在該位置的value爲對象a

此行Process(a)傳遞對象的VALUEa不是地址運作Process,所以有什麼事情發生在Process()無關與contents的地址*(0x12DF)相關,因此地址*(0x12DF)的內容將保持與撥打Process()之前的相同。

*(0x12DF)內容=一

我希望它有幫助的,而不是創造更多的混亂!

+0

我認爲_Process(a)_傳遞內容的地址。 _Process(aclass a)_中的參數是一個指向相同內容0x12DF的新對象。 0x12DF中的內容從未被複制過。傳遞地址比傳遞整個值更有效。如果_aclass_是一個值類型,則參數_a_將是一個新的對象,其值在不同的地址重複。 – mortdale

0

它基本上是

  • 按值傳遞引用類型之間的差//方法(a);
  • 通過引用傳遞引用類型// Process(ref a);

在示例中,Process(a) - 作爲引用類型的'a'被傳遞給沒有ref參數的方法。在這種情況下,將指向a的引用副本傳遞給該方法。

通過在Process方法中使用new運算符分配新內存部分,使得變量'a'引用了aclass的新對象。因此,之後的任何更改都不會影響原始對象'a'。

參見MSDN:http://msdn.microsoft.com/en-us/library/s6938f28.aspx