我有一个修改对象的委托。我从调用方法传递一个对象到委托,但调用方法不会获取这些更改。如果我传递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);
答案 0 :(得分:105)
对象不通过引用传递。根本没有传递对象。
默认情况下,参数的值按值传递 - 无论该值是值类型值还是引用。如果通过该引用修改了对象,那么该更改也将对调用代码可见。
在您最初显示的代码中,没有理由使用ref
。如果您需要一个更改参数值的方法(例如,使其完全引用另一个对象)并让调用者可以看到该更改,则使用ref
关键字。 / p>
现在,在您(最初)展示的代码中,您只有:
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
。
如果您可以展示一个简短但完整的程序来演示您的问题,那么解释发生的事情就会轻松得多。
在几个段落中很难做到这个主题正义 - 所以我有一个entire article about it,这将有希望使事情变得更加明显。