在 C# 中通过引用传递对象和对象列表

Posted

技术标签:

【中文标题】在 C# 中通过引用传递对象和对象列表【英文标题】:Passing objects and a list of objects by reference in C# 【发布时间】:2011-03-03 16:21:15 【问题描述】:

我有一个修改对象的委托。我从调用方法将对象传递给委托,但是调用方法不会获取这些更改。如果我将 List 作为对象传递,则相同的代码可以工作。

我认为所有对象都是通过引用传递的,因此任何修改都会反映在调用方法中。对吗?

我可以修改我的代码以将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);

【问题讨论】:

我知道你在这里试图隐藏原来的名字,但你必须把它清理干净。 MyBinder 内部 CallingMethod 未定义,MyObjectBinder 未使用...它们相同吗?我只能尝试假设,我不想那样做...... 【参考方案1】:

对象不是通过引用传递的。根本不传递对象。

默认情况下,参数的值是按值传递的——无论该值是值类型值还是引用。如果通过该引用修改了对象,那么调用代码也将看到该更改。

在您最初显示的代码中,没有理由使用refref 关键字用于当您想要一个更改 参数 值的方法(例如,使其完全引用不同的对象)并使调用者可以看到该更改。

现在,在您(最初)显示的代码中,您只有:

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,希望它能让事情变得更明显。

【讨论】:

感谢更新的答案。是的,问题是因为在 BindMyObject 中我正在初始化一个新对象。自己调试才发现这个。 @David Liddle - 您可能希望在原始主题中包含更改后的代码,以便人们看到您最终使用的内容。所以我认为你最终使用 REF 是因为你的代码新建了一个新的 myObject? @JonH:我已经稍微修改了我的答案以使其更清楚,因为代码已更改:)

以上是关于在 C# 中通过引用传递对象和对象列表的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中通过引用传递对象

在 C++11 中通过引用 std::thread 传递对象

为啥我们需要一个默认构造函数来在 C++ 中通过引用传递一个对象?

在 C++ 中通过引用/值传递

在Java中通过引用等效?

在 Javascript 中通过引用传递字符串