2009-01-12 83 views
4

更新所以完全拉了一個工具時刻。我的意思是通過參考與出/參考。凡是說 '裁判' 我真的被引用意味着在C#Out參數問題:Out如何處理值類型?

的someMethod(對象someObject)

對戰

的someMethod(出someObject)

對不起。只是不想更改代碼,所以答案已經有意義。

據我所知,不像裁判那裏「複製」指針並創建堆棧上的新空間,使用指針,但不會改變指針:

SomeMethod() 
{ 
SomeThing outer = new SomeThing(); 
RefMethod(ref outer) 
} 

RefMethod(ref inner) //new space on stack created and uses same pointer as outer 
{ 
    inner.Hi = "There"; //updated the object being pointed to by outer 
    inner = new SomeThing();//Given a new pointer, no longer shares pointer with outer 
          //New object on the heap 
} 

出副本指針,可以操縱它指向的:

SomeMethod() 
{ 
SomeThing outer = new SomeThing(); 
RefMethod(out outer) 
} 

RefMethod(out inner) //same pointer shared 
{ 

    inner = new SomeThing();//pointer now points to new place on heap 
          //outer now points to new object 
          //Old object is orphaned if nothing else points to it 
} 

這很好,很正常,使用對象,但對於值類型看到,因爲他們沒有什麼指向僅爲堆棧?

回答

9

僅僅因爲變量存在於棧上(如果它是一個局部變量)並不意味着你不能創建一個指向它的指針 - 事實上,引用類型也是如此。

RefMethod中的指針指向「外部」變量 - 並且變量本身位於堆棧上,因爲它是未捕獲的局部變量。

正如Leppie所說,除了關於明確賦值的規則外,ref和out是相同的 - 事實上,IL中唯一的區別是應用於輸出參數的屬性。

查看my article on parameter passing瞭解更多有關ref/out的細節。

3

就我所知,ref和out是完全一樣的,只是out參數不能被初始化。因此兩者都在堆疊中。

+0

我認爲你的意思是一個out參數*有*必須在方法內的正常返回之前明確賦值;一個用作out參數的變量不必在調用之前明確賦值,儘管它可以是。 (這將在之後。) – 2009-01-12 19:53:35

+0

要添加到Jon所說的,ref參數必須被初始化,並且out參數不必是(但可以)。 – 2009-01-12 19:56:49

1

實際上使用ref或out引用類型也會創建一個指針...不是指向對象,而是指向對象的引用! 因此,這將是某種

RefMethod(SomeThing **inner) 
{ 
} 
在C++

,而值類型這將是

RefMethod2(int *inner) 
{ 
} 

值類型。