我正在通过C#阅读Jeffrey Richters CLR,并在其中用ref参数说,引用本身是按值传递的。这对我来说很有意义,而且似乎与指针类似。
即。在C中,如果我将一个指针传递给一个函数,然后通过malloc分配指针,它将指针更改为指向新的内存位置,但是我知道,因为指针本身是一个副本,它不会重新分配传递的原始指针进入功能。为了完成对函数外部指针的更改,我必须使用双指针。
然而,在C#中:
void Swap(ref Object a, ref Object b)
{
Object t = b;
b = a;
a =t ;
}
的工作原理。这向我表明参考不是按价值。 与上面的malloc类似,我假设我可以通过引用传递一个对象并为其分配一个新对象,并且重新分配将在函数外部保留。
有人可以澄清我的困惑吗?
答案 0 :(得分:6)
你略微偏了。对于引用类型,引用是按值传递。传递 ref
参数是不同的。在
private void Frob(Foo foo) // Foo is a class
{
}
调用站点上类型为Foo
的对象的引用副本将传递给方法Frob
。此引用的副本按值传递。此引用和调用站点上的引用指向内存中的同一对象,并将继续这样做,直到其中一个指向内存中的其他对象。例如,如果在此方法中,我们编写
foo = someOtherFoo;
然后该参数不再引用与呼叫站点上的对象相同的对象。呼叫站点引用未更改。
现在考虑我们是否引入ref
关键字。
private void Frob(ref Foo foo)
{
foo = someOtherFoo;
}
在这种情况下,foo
是呼叫站点变量的别名。这些变量不只是指向内存中的同一个对象,就好像它们是同一个变量!因此,将foo
指向someOtherFoo
不仅会在此方法中更改foo
,此更改也会反映在呼叫网站上。
答案 1 :(得分:5)
如果没有ref
关键字,则按值传递对象的引用。
使用ref
关键字,通过值传递对象引用的引用。
[只是编译器隐藏了这样一个事实,即对由显式ref
传递的参数进行赋值正在改变指针]
答案 2 :(得分:0)
调用时,它会传递原始指针值(引用)
void Swap(ref Object a, ref Object b)
{
Object t = b;
b = a;
a = t;
}
这会传递原始指针的副本:
void Swap(Object a, Object b)
{
Object t = b;
b = a;
a = t;
}
两者都将指向同一个对象,但更改第二个将不会反映在此方法的更大范围内...
虽然我没有提出这个问题......