2010-07-31 58 views
0

我已經創建了一個類,它接受一個參數作爲參數。當它在構造中使用這個對象時,它是空的。爲什麼它保持空(未初始化)?如何在C#中使用ref#

// example code, not real 
class Test{ 
    object parent; 

    public Test (ref object _parent) 
    { 
     parent = _parent; 
    } 
} 

object n = null; 
Test t = new Test (ref n); 
n = new Something(); 

當我用不同類(http://pastebin.com/PpbKEufr)試了一下,留下空

+0

這是爲什麼被壓低投票? – 2010-07-31 12:46:01

+0

@Merlyn因爲運行代碼需要更少的時間,並且看看會發生什麼,而不是將它發佈到SO上。更好的問題會問*爲什麼*。 – dbkk 2010-07-31 12:52:00

+0

@dbkk:問題可能不是完美的措詞,但將其解讀爲「爲什麼會發生這種情況」或「我怎樣才能讓它做我想做的事情」。 – 2010-07-31 12:56:46

回答

4

是的,parent將留null無論你最終分配給變量nref關鍵字將實際引用傳遞給n(與其副本相反)到您的方法中,並且通常在您的方法旨在將新對象實例分配給參數時使用。

在您的方法中,您正在製作n指向的參考副本,在此例中爲null。當該方法完成時nparent指向null。當您稍後分配給n時,您並未更改n和父點的對象,而是要求n指向新位置,而parent仍指向null

如果您要創建對象的實例並將其指定給n,那麼parent將指向同一對象,並且對該類的任何更改都將可見。如果您沒有傳遞參數ref,情況也會如此,因爲參考副本也會指向同一個對象實例。

希望有所幫助。

1

在C#裁判參數引用的實例「指出」通過論證。

例如,如果你在構造改變_parent並將其存儲在其他情況下,則n將隨之改變。

在發佈代碼你複製引用的實例(null)到parent。意思是,它將引用的實例複製到字段中,而不是參數本身的引用。

例如,方法改變裁判論點:

public void M(ref object arg) 
{ 
    arg = new object(); 
} 

以及使用例如:

[Test] 
public void SetReferenceArgument() 
{ 
    var myClass = new MyClass(); 
    object arg = null; 
    myClass.M(ref arg); 

    Assert.That(arg, Is.Not.Null); 
} 

REF參數讓我們指定實例成將兩者在改變基準參數方法和調用者的上下文中。

2

這是不可能的,因爲這將打破encapsulation的想法改變一個類的私人成員。

爲了更改(即替換)存儲在專用字段中的對象,您必須通過該類的公共屬性或方法明確地執行此操作。

class Test 
{ 
    object parent; 

    public Test (ref object _parent) 
    { 
     parent = _parent; 
    } 

    public object Parent 
    { 
     get { return parent; } 
     set { parent = value; } 
    } 
} 

object n = null; 
Test t = new Test (ref n); 
n = new Something(); 
t.Parent = n; 

這樣,語言可以確保對象的數據不會(意外)從外部改變,這可能會導致最奇怪的效果。