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

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

Ответ 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.

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

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