C# - Ref类型比较指针混乱?

时间:2011-04-29 03:09:34

标签: c# c pointers ref

我正在通过C#阅读Jeffrey Richters CLR,并在其中用ref参数说,引用本身是按值传递的。这对我来说很有意义,而且似乎与指针类似。

即。在C中,如果我将一个指针传递给一个函数,然后通过malloc分配指针,它将指针更改为指向新的内存位置,但是我知道,因为指针本身是一个副本,它不会重新分配传递的原始指针进入功能。为了完成对函数外部指针的更改,我必须使用双指针。

然而,在C#中:

void Swap(ref Object a, ref Object b)
{
    Object t = b;
    b = a;
    a =t ;
}

的工作原理。这向我表明参考不是按价值。 与上面的malloc类似,我假设我可以通过引用传递一个对象并为其分配一个新对象,并且重新分配将在函数外部保留。

有人可以澄清我的困惑吗?

3 个答案:

答案 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;
}

两者都将指向同一个对象,但更改第二个将不会反映在此方法的更大范围内...

虽然我没有提出这个问题......