我知道,如果我传递一个值类型(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'你必须在接收方法中赋值。

其他回答

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

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

它允许您修改传入的引用。如。

void Bar()
{
    var y = new Foo();
    Baz(ref y);
}

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

    // Overwrite the reference
    y = new Foo();
}

如果你不关心传入的引用,你也可以使用out:

void Bar()
{
    var y = new Foo();
    Baz(out y);
}

void Baz(out Foo y)
{
    // Return a new reference
    y = new Foo();
}

你可以用y来改变foo指向的东西:

Foo foo = new Foo("1");

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

Bar(ref foo);
// foo.Name == "2"

这里解释得很好: 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.

另一组代码

class O
{
    public int prop = 0;
}

class Program
{
    static void Main(string[] args)
    {
        O o1 = new O();
        o1.prop = 1;

        O o2 = new O();
        o2.prop = 2;

        o1modifier(o1);
        o2modifier(ref o2);

        Console.WriteLine("1 : " + o1.prop.ToString());
        Console.WriteLine("2 : " + o2.prop.ToString());
        Console.ReadLine();
    }

    static void o1modifier(O o)
    {
        o = new O();
        o.prop = 3;
    }

    static void o2modifier(ref O o)
    {
        o = new O();
        o.prop = 4;
    }
}