我知道,如果我传递一个值类型(int, struct等)作为参数(没有ref关键字),该变量的副本将传递给方法,但如果我使用ref关键字,则传递对该变量的引用,而不是一个新变量。

但是对于引用类型,就像类一样,即使没有ref关键字,也会将引用传递给方法,而不是副本。那么ref关键字与reference-types有什么用呢?


举个例子:

var x = new Foo();

以下两种有什么区别?

void Bar(Foo y) {
    y.Name = "2";
}

and

void Bar(ref Foo y) {
    y.Name = "2";
}

当前回答

当您传递带有ref关键字的引用类型时,您逐个引用传递引用,并且您调用的方法可以为参数分配一个新值。该更改将传播到调用作用域。如果没有ref,引用是按值传递的,这不会发生。

c#也有'out'关键字,它很像ref,除了使用'ref',参数必须在调用方法之前初始化,使用'out'你必须在接收方法中赋值。

其他回答

这里解释得很好: http://msdn.microsoft.com/en-us/library/s6938f28.aspx

文章摘要:

A variable of a reference type does not contain its data directly; it contains a reference to its data. When you pass a reference-type parameter by value, it is possible to change the data pointed to by the reference, such as the value of a class member. However, you cannot change the value of the reference itself; that is, you cannot use the same reference to allocate memory for a new class and have it persist outside the block. To do that, pass the parameter using the ref or out keyword.

引用变量携带地址从一个地方到另一个地方,所以任何地方对它们的更新都会反映到所有地方,那么REF有什么用。 引用变量(405)是有效的,直到没有新的内存分配给在方法中传递的引用变量。

一旦分配了新的内存(410),那么这个对象(408)上的值变化将不会反映在所有地方。 裁判来了。Ref是引用的引用,所以每当分配新的内存时,它就会知道,因为它指向那个位置,因此这个值可以被每个人共享。您可以更清楚地看到图像。

Jon Skeet写了一篇关于c#参数传递的很棒的文章。它清楚地详细描述了按值、按引用(ref)和按输出(out)传递参数的确切行为和用法。

下面是该页关于ref参数的重要引用:

Reference parameters don't pass the values of the variables used in the function member invocation - they use the variables themselves. Rather than creating a new storage location for the variable in the function member declaration, the same storage location is used, so the value of the variable in the function member and the value of the reference parameter will always be the same. Reference parameters need the ref modifier as part of both the declaration and the invocation - that means it's always clear when you're passing something by reference.

当您传递带有ref关键字的引用类型时,您逐个引用传递引用,并且您调用的方法可以为参数分配一个新值。该更改将传播到调用作用域。如果没有ref,引用是按值传递的,这不会发生。

c#也有'out'关键字,它很像ref,除了使用'ref',参数必须在调用方法之前初始化,使用'out'你必须在接收方法中赋值。

除了现有的答案:

正如你所要求的2种方法的差异:使用ref或out时没有co(ntra)方差:

class Foo { }
class FooBar : Foo { }

static void Bar(Foo foo) { }
static void Bar(ref Foo foo) { foo = new Foo(); }

void Main()
{
    Foo foo = null;
    Bar(foo);           // OK
    Bar(ref foo);       // OK

    FooBar fooBar = null;
    Bar(fooBar);        // OK (covariance)
    Bar(ref fooBar);    // compile time error
}