我知道,如果我传递一个值类型(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";
}

当前回答

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

Foo foo = new Foo("1");

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

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

其他回答

当您传递带有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();
}

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

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

A parameter in a method seems to be always passing a copy, the question is a copy of what. A copy is done by a copy constructor for an object and since all variables are Object in C#, i believe this is the case for all of them. Variables(objects) are like people living at some addresses. We either change the people living at those addresses or we can create more references to the people living at those addresses in the phone book(make shallow copies). So, more than one identifier can refer to the same address. Reference types desire more space, so unlike value types that are directly connected by an arrow to their identifier in the stack, they have value for another address in the heap( a bigger space to dwell). This space needs to be taken from the heap.

值类型: 标识符(包含值=堆栈值的地址)---->值类型的值

引用类型: 标识符(包含值=堆栈值的地址)---->(包含值=堆值的地址)---->堆值(通常包含到其他值的地址),想象更多的箭头指向数组[0],数组[1],数组[2]

更改值的唯一方法是遵循箭头。如果一个箭头丢失/改变了该值不可达的方式。

另一组代码

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