0

所以我正在浏览 Illustrated C# 2012,除了本章的这一部分,我基本上得到了一切,下面是源代码:

class MyClass
{
    public int Val = 20;
}

class Program
{
    static void RefAsParameter(MyClass f1)
    {
        f1.Val = 50;
        Console.WriteLine( "After member assignment: {0}", f1.Val );
        f1 = new MyClass();
        Console.WriteLine( "After new object creation: {0}", f1.Val );
    }

    static void Main()
    {
        MyClass a1 = new MyClass();
        Console.WriteLine( "Before method call: {0}", a1.Val );
        RefAsParameter( a1 );
        Console.WriteLine( "After method call: {0}", a1.Val );
    }
}

此代码产生以下输出:

Before method call: 20
After member assignment: 50
After new object creation: 20
After method call: 50

所以......我基本上理解了最后一个 Console.WriteLine() 的大部分内容。为什么它是 50“方法调用后”。既然它创建了一个新的“MyClass()”,它不应该还是 20 吗?显然我错过了一些非常明显的东西。是因为 f1.Val “永远”改变了 Myclass Public 价值还是什么?

对此有点困惑。谢谢。我总体上理解“参考”,这让我有点难过。

4

3 回答 3

3

线

f1 = new MyClass();

重新分配变量f1以指向一个新的MyClass. 它不会改变a1变量。

如果将方法更改为:

static void RefAsParameter( ref MyClass f1 )

然后它改变a1变量,你会得到:

After method call: 20
于 2013-08-27T02:08:06.577 回答
3

看哪..我很棒的绘画技巧:

在此处输入图像描述

点击这里查看完整图片

f1在方法中使用时,它是一个指向内存中同一个对象的新引用。当您使用 重新分配引用时f1 = new MyClass();,您实际上是在说“好的,此引用现在指向一个新实例”。这保持a1不变.. 所以当函数展开并点击 时Console.WriteLine,您的a1引用仍然引用旧的内存区域.. 现在它的属性设置为 50。

要获得您期望的行为,请将对象作为ref参数传入:

static void RefAsParameter(ref MyClass f1)
于 2013-08-27T02:17:34.627 回答
1

当一个对象被引用时,并不意味着它在复制自己。这意味着我们指向具有两个不同名称的同一个对象。这里a1f1都引用同一个对象,这就是为什么如果我们使用改变值,f1那么值也会改变a1

稍后您将创建另一个实例并将引用分配给f1. 所以 nowf1将无法再访问以前的对象,而且 nowa1f1不会引用同一个对象。

于 2013-08-27T02:15:02.843 回答