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



ref и out c# (1)

У меня есть делегат, который изменяет объект. Я передаю объект делегату из вызывающего метода, однако вызывающий метод не подбирает эти изменения. Тот же код работает, если я передаю 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 делегату, поскольку я BindMyObject новый объект внутри BindMyObject .

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

Answer #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 не прочитав его, вы должны использовать вместо ref .

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

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





pass-by-reference