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 }
更新
当我在BindMyObject中实例化一个新的对象时,我通过ref传递给委托对象。
protected delegate int MyBinder<T>(object reader, ref T myObject);
对象不通过引用传递。 对象根本不通过。
默认情况下,参数的值是按值传递的 – 无论该值是值types值还是引用。 如果通过该引用修改了对象,那么对于调用代码来说,该更改也是可见的。
在您最初显示的代码中,没有理由使用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
。
如果您可以展示一个简短而完整的程序来展示您的问题,那么解释发生的事情会更容易。
在短短的几段时间内就很难做到这一点,所以我已经有了一篇关于这个话题的文章 ,希望能够让事情变得更加明显。