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

发布于 2024-09-06 03:05:57 字数 1358 浏览 14 评论 0原文

我有一个修改对象的委托。我从调用方法将对象传递给委托,但是调用方法不会接受这些更改。如果我将 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
}

更新

当我在 BindMyObject 中实例化一个新对象时,我现在通过 ref 将对象传递给委托。

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

I have a delegate that modifies an object. I pass an object to the delegate from a calling method, however the calling method does not pick up these changes. The same code works if I pass a List as the object.

I thought all objects were passed by reference so any modifications would be reflected in the calling method. Is that correct?

I can modify my code to pass a ref object to the delegate. But I am wondering why this is necessary. Or is it?

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
}

Update:

I am now passing objects by ref to the delegate as I am instantiating a new object inside BindMyObject.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨敛清荷 2024-09-13 03:05:57

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

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

在您最初显示的代码中,没有理由使用 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< /代码>。

如果您可以展示一个简短但完整的程序来说明您的问题,那么解释发生的事情就会容易得多。

很难用几段文字来阐述这个主题 - 所以我有一篇整篇文章它,这有望让事情变得更加明显。

Objects aren't passed by reference. Objects aren't passed at all.

By default, the value of the argument is passed by value - whether that value is a value type value or a reference. If an object is modified via that reference, then that change will be visible to the calling code as well.

In the code you showed originally, there was no reason to use ref. The ref keyword is used when you want a method that changes the value of a parameter (e.g. to make it refer to a different object entirely) and have that change visible to the caller.

Now, in the code you've shown (originally) you've only got:

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

Do you mean code like this:

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

or code like this:

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

? If it's the latter, then you don't need ref. If it's the former, then you do need ref because you're changing the parameter itself, not making changes to the object that the value refers to. In fact, if you're just setting the value of obj without ever reading it, you should use out instead of ref.

If you can show a short but complete program which demonstrates your problem, it'll be a lot easier to explain what's going on.

It's hard to do this topic justice in just a few paragraphs - so I've got an entire article about it, which will hopefully make things more obvious.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文