所以我通过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值“for good”还是什么?
对此略有困惑。谢谢。 我理解“参考文献”一般来说这个我只是有点难过。
答案 0 :(得分:3)
该行
f1 = new MyClass();
重新指定变量f1
以指向新的MyClass
。它不会更改a1
变量。
如果您将方法更改为:
static void RefAsParameter( ref MyClass f1 )
然后将更改a1
变量,您将获得:
After method call: 20
答案 1 :(得分:3)
看哪..我很棒的油漆技巧:
(Click here for the full image)
在方法中使用f1
时,它是新引用,指向内存中的同一对象。当您使用f1 = new MyClass();
重新分配引用时,您实际上是在说“好吧,此引用现在指向一个新实例”。这使a1
保持不变..因此,当函数展开并点击Console.WriteLine
时,您的a1
引用仍引用旧的内存区域...现在属性设置为50。 / p>
要获得您期望的行为,请将对象作为ref
参数传递:
static void RefAsParameter(ref MyClass f1)
答案 2 :(得分:1)
引用对象时,并不意味着它本身就是在复制。这意味着我们指向具有两个不同名称的同一对象。此处a1
和f1
都引用了相同的对象,这就是为什么我们使用f1
更改值时所以a1
的值也在变化。
稍后您将创建另一个实例并将引用分配给f1
。因此,现在f1
将无法再访问上一个对象,现在a1
和f1
将不会引用同一个对象。