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

标签 c# pass-by-reference

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

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

我可以修改我的代码以将 ref 对象传递给委托(delegate)。但我想知道为什么这是必要的。或者是?

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 将对象传递给委托(delegate),因为我正在 BindMyObject 中实例化一个新对象。

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

最佳答案

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

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

在您最初展示的代码中,没有理由使用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 ,这有望使事情变得更加明显。

关于c# - 在 C# 中通过引用传递对象和对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3040170/

相关文章:

c# - CosmosDB 查询性能

C# 并非所有代码路径都返回值数据收集器类项目

java - Java 是 "pass-by-reference"还是 "pass-by-value"?

c# - 使用 ConfigurationManager 访问 v3.5 Azure WebJob 中的 App.config

c# - 系统.MissingMethodException : Method 'Android.Support.V4.Widget.DrawerLayout.AddDrawerListener' not found

c++ - 我可以在 C++ 中通过引用传递多少个参数,而不会出现异常行为

c++ - 为什么我不能在从算术运算符返回时将此类作为引用传递?

java - 按引用还是按值变量? java

c# - 傻瓜式 SSL

c++ - 将临时对象作为参数传递 (C++)