2010-12-21 64 views
0

可能重複:
When to pass ref keyword in當在一個方法中通過ref傳遞並且在C#中沒有引用時有什麼區別?

大家好,

我只是驚訝,爲什麼我們在C#中有ref,而默認的一切是在C#中的引用類型作爲參考傳遞。

在簡單的話,任何人都可以給我解釋一下這兩種方法之間的區別來電:

public void Test(SomeClass someClass) 
{ 
    // some code here 
} 

public void Test(ref SomeClass someClass) 
{ 
    // some code here 
} 

在我的思想它們都具有參考相同的內存位置。

那麼,爲什麼我們需要關鍵字ref呢?

回答

2

當你傳遞一個對象時,你通過引用傳遞它。這意味着你對該對象所做的任何事情都會在方法返回後反映到對象中。當您通過引用傳遞引用,即void Foo(ref object obj)時,您正在傳遞該對象的地址。然後,您可以在地址重新分配給不同的對象,這將是國家的事情,當該方法返回

foo (object o) 
{ 
    ... 
} 

var v = new object(); 
foo(v); 

v仍然會引用在調用之前實例化foo的同一對象

void bar(ref object o) 
{ 
    o = null; 
} 

var v = new object(); 
foo(ref v); 
// v is now null 
8

ref關鍵字將引用傳遞給存儲引用的任何位置。這允許你從被調用的函數中操縱這個變量。這對值類型特別有用,但在與引用類型一起使用時也有用處。 (Dictionary.TryGetValue()是一個很好的例子的out參數是必需的,返回存儲在字典的值out相當於ref不同之處在於它會經歷一組不同的編譯時檢查的。)

例如:

public void Test(ref SomeClass obj) 
{ 
    obj = null; 
} 

public void Test2(SomeClass obj) 
{ 
    obj = null; 
} 

public void Foo() 
{ 
    SomeClass obj = new SomeClass(); 
    Test(ref obj); 
    // obj is null here! 

    obj = new SomeClass(); 
    Test2(obj); 
    // obj is not null here. 
} 
+0

在調用test2之後,obj確實是null – Chandu 2010-12-21 21:00:23

+4

@Cyber​​nate:不,它不會。編譯併爲自己測試。 `Test2`中的`obj = null`行只會將參數變量設置爲null;它不會影響`Foo`中的`obj`本地。 – cdhowie 2010-12-21 21:01:19

+0

我的不好...你是對的。今天學到了一件新事物:)。將我的投票添加到答案... – Chandu 2010-12-21 21:05:29

3

我只是感到驚訝,爲什麼我們在C#中引用默認情況下,一切都是C#中的引用類型作爲引用傳遞。

因爲C#中的某些東西是值類型,有時我們想要通過這些值。我們有ref關鍵字,以便這些東西可以通過引用傳遞。

3

它類似於C++中SomeClass *SomeClass **之間的區別。

使用SomeClass *(或沒有ref),我們可以修改指向的對象,但是我們不能將它重定向到一個全新的對象。

使用SomeClass **(或使用ref),我們可以更改調用代碼中的參數,以便將其指向我們選擇的對象。

0

假設方法Foo按值接受一個Bar。如果我有一個名爲「博茲」吧,語句:

 
    Foo(Boz); 

可能採取目的在於通過博茲指出,改變該對象的特徵,但它不能改變對象博茲點。相反,如果Boz被引用通過,同樣的陳述可能導致Boz完全指向一個不同的對象。

作爲使用示例,請考慮接受數組作爲參數的例程。如果數組按值傳遞,則收件人可以更改數組中任何項目的值,但收件人無法更改大小。更改數組大小的唯一方法是創建一個新數組,將舊數據項複製到該數組中,然後使用新數組而不是舊數組。當數組按值傳遞時,接收者無法告訴調用者應該停止使用舊數組,而是使用新數組。通過引用傳遞的數組不是問題。

相關問題