Передача объектов и списка объектов ссылкой в C#

У меня есть делегат, который изменяет объект. Я передаю объект делегату от вызывающего метода, однако вызывающий метод не берет эти изменения. Тот же код работает, если я передаю a List как объект.

Я думал, что все объекты были переданы ссылкой, таким образом, любые модификации будут отражены в вызывающем методе. Это корректно?

Я могу изменить свой код для передачи a 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);
40
задан DavidRR 8 February 2018 в 16:02
поделиться

1 ответ

Объекты не передаются по ссылке. Объекты вообще не передаются.

По умолчанию значение аргумента передается по значению - независимо от того, является ли это значение значением типа значения или ссылкой. Если объект изменен с помощью этой ссылки, то это изменение также будет видно вызывающему коду.

В коде, который вы показали изначально, не было причин использовать 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 .

Если вы можете показать короткую, но полную программу, которая демонстрирует вашу проблему, вам будет намного проще объяснить, что происходит.

Трудно описать эту тему в нескольких абзацах - поэтому у меня есть целая статья об этом , которая, надеюсь, сделает вещи более очевидными.

105
ответ дан 27 November 2019 в 01:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: