2010-06-14 162 views
39

我有一個修改對象的委託。我將一個對象從調用方法傳遞給委託,但調用方法不會選擇這些更改。如果我將List作爲對象,則相同的代碼有效。在C#中通過引用傳遞對象和對象列表#

我認爲所有的對象都通過引用傳遞,所以任何修改都會反映在調用方法中。那是對的嗎?

我可以修改我的代碼,將ref對象傳遞給委託。但我想知道爲什麼這是必要的。或者是?

public class Binder 
{ 
    protected delegate int MyBinder<T>(object reader, T myObject); 

    public void BindIt<T>(object reader, T myObject) 
    { 
     //m_binders is a hashtable of binder objects 
     MyBinder<T> binder = m_binders["test"] as MyBinder<T>; 
     int i = binder(reader, myObject); 
    } 
} 

public class MyObjectBinder 
{ 
    public MyObjectBinder() 
    { 
     m_delegates["test"] = new MyBinder<MyObject>(BindMyObject); 
    } 

    private int BindMyObject(object reader, MyObject obj) 
    { 
     obj = new MyObject 
     { 
      //update properties 
     }; 
     return 1; 
    } 
} 

///calling method in some other class 
public void CallingMethod() 
{ 
    MyObject obj = new MyObject(); 

    MyObjectBinder binder = new MyObjectBinder(); 
    binder.BindIt(myReader, obj); //don't worry about myReader 

    //obj should show reflected changes 
} 

更新:

我現在傳遞對象通過ref的委託作爲我裏面實例化一個BindMyObject新對象。

protected delegate int MyBinder<T>(object reader, ref T myObject); 
+1

我意識到你試圖隱藏原來的名字,但是你必須清理它。 'CallingMethod'內的'MyBinder'沒有定義,'MyObjectBinder'沒有被使用......它們是相同的嗎?我只能嘗試假設,並且我不想那麼做... – Randolpho 2010-06-14 19:22:11

回答

103

對象未通過引用傳遞。對象根本不通過。

默認情況下,參數的值按值傳遞 - 無論該值是值類型值還是引用。如果通過該引用修改了對象,那麼對於調用代碼也會看到該更改。

在您最初顯示的代碼中,沒有理由使用ref。當您需要一種方法來更改參數的值(例如,使其完全引用不同的對象)並使該更改對調用者可見時,將使用ref關鍵字。現在

,在代碼中你已經證明(原本)你只得到了:

private int BindMyObject(object reader, MyObject obj) 
{ 
    //make changes to obj in here 
} 

你的意思是這樣的代碼:

private int BindMyObject(object reader, MyObject obj) 
{ 
    obj = new MyObject(); 
} 

或這樣的代碼:

private int BindMyObject(object reader, MyObject obj) 
{ 
    obj.SomeProperty = differentValue; 
} 

?如果是後者,那麼你不需要ref。如果它是前者,那麼你需要ref,因爲你正在改變參數本身,而不是改變該值所引用的對象。事實上,如果你是只是設置值obj而沒有閱讀它,你應該使用out而不是ref

如果你可以顯示一個簡短的,但完整的程序,它演示你的問題,它會更容易解釋發生了什麼事情。

很難在短短的幾段內討論這個話題 - 所以我得到了一個entire article about it,希望能讓事情變得更加明顯。

+1

感謝您的更新答案。是的,問題是因爲在BindMyObject中我正在初始化一個新的對象。只是發現了這一點調試自己。 – David 2010-06-14 19:28:42

+1

@David Liddle - 您可能希望將更改後的代碼包含在原始主題中,這樣人們就能看到您最終使用的內容。所以我認爲你最終使用REF是你的代碼new'ed一個新的myObject? – JonH 2010-06-14 19:46:27

+1

@JonH:我修改了我的答案,使其更清晰,現在代碼已被更改:) – 2010-06-14 19:58:21