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