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