2011-04-21 72 views
3

如果我有一個方法,如:返回值存儲器範圍

public SomeObject GetObject(int ID){ 

    SomeObject obj1 = new SomeObject(); 

    obj1.ID = ID; 

    return obj1; 
} 

然後,如果我用這樣的方法:

SomeObject obj2 = GetObject(4); 

威爾obj2簡單地是obj1在存儲器中的參考,或將它被複制到內存中並存在兩個完整的對象?

如果後者爲真,GC何時會從內存中刪除obj1

回答

5

這取決於類型。有價值類型和參考類型。

Value types將值本身存儲在內存中,每次將值傳遞給它時,只需複製值(因此,值類型),除非使用類似public void Test(ref int x)之類的值。 ref有這個意思是通過引用傳遞整數。

當你有一個reference type(對象)的變量時,你基本上只是保持一個指針。所以它會傳遞與對象相同的引用。

您可以通過擴展您的代碼做這樣的事情證實了這一點:

obj2.ID = 3; 
Console.WriteLine(obj1.ID); // => 3 

OBJ1(或對象本身,因爲OBJ1只是一個參考)將GC'd時不再有任何引用到物體。

1

obj1的存儲器中,這將是一個參考,假設obj1class而不是struct

0

如果某個對象是一個引用類型,那麼你會得到一個引用副本,如果SomeObject是一個值類型,你會得到一個副本。垃圾收集器會在稍後決定釋放內存時清理SomeObject。但是,您可以通過調用GC強制執行GC手。收集

3

如果SomeObject從ValueType延遲,那麼位於GetObject作用域中的實例將在其返回時立即銷燬並創建新實例並將其分配給obj2。 如果SomeObject不是一個ValueType,也就是引用類型,那麼只有它的引用將被返回,所以你最終得到1個實例。 不可能預測GC何時會銷燬一個對象,但是,GC只會銷燬引用類型,當代碼執行超出其範圍時,ValueType會自動銷燬。

2

將OBJ2僅僅是在內存中OBJ1
是一個參考值(假設它不是一個數值型)

但是有一點要注意:對象始終按值參數傳遞,所以如果你改變GetObject的:

public class SomeObject 
{ 
    public string Name { get; set; } 
    public int ID { get; set; } 
    public SomeObject() { ID = 1; Name = "test"; } 
} 

static void Main(string[] args) 
{ 
    SomeObject obj1 = new SomeObject(); 
    GetObject(obj1, 2); 

    Console.WriteLine(obj1.ID); // prints 1 
    Console.Read(); 
} 

public static void GetObject(SomeObject obj1, int id) 
{ 
    var obj = new SomeObject(); 
    obj.ID = id; 
    obj.Name = ""; 

    obj1 = obj; 
} 
+0

對象實際上並未「按價值」傳遞。他們的引用是通過價值傳遞的。 – Ryan 2011-05-16 18:03:20

+0

@minitech我不確定我說他們不是 – 2011-05-16 19:51:45

+0

但這只是令人困惑,因爲問題是詢問對象的內容是否被複制,而您的示例與此無關。 – Ryan 2011-05-16 22:28:03

2

假設SomeObject是一個類,該方法將一個參考返回到對象實例,它創建。

對象實例不會被複制,只有一個實例。在。除非您特別要求複製,例如通過調用Clone方法,否則不會複製任何對象。

在談論引用類型時,重要的是要記住對象實例,對實例的引用和包含引用的變量之間的區別。變量obj1保存對該實例的引用,並且該變量被分配到該方法的堆棧幀中,因此當您退出該方法時它會消失。該引用從該方法返回,但當時該變量不再存在。