我有以下示例代码:
public class MyClass
{
public int Value { get; set; }
}
class Program
{
public static void Foo(MyClass v)
{
v.Value = 2;
v = new MyClass();
v.Value = 3;
}
static void Main(string[] args)
{
var m = new MyClass();
m.Value = 1;
Foo(m);
Console.Write(m.Value);
Console.ReadLine();
}
}
我想了解为什么输出是2而不是3,请您给我一些清楚的解释吗?
谢谢
我将通过调试器逐步介绍您,我们将看到它是什么2。
我们看到进入Foo并通过引用传递了MyClass的实例v
(默认情况下,通过引用传递了C#中的类实例)
在内存中,我们将看到以下内容:
v = 0x01; //0x01 - is a simple representation of a pointer that we passed
v.Value = 1;
接下来,我们走过去,我们看到我们更改了引用中的值Value。
v = 0x01;
v.Value = 2; // our new value
然后我们分配new
给v
内存中的
v* = 0x01 // this is our "old" object
v*.Value = 2;
v = 0x02 // this is our "new" object
v.Value = 3;
如您所见,内存中有2个对象!新一v
和旧标有启动v*
当我们退出该方法时,我们没有替换内存地址的内容,0x01
而是创建了v
函数范围的本地副本,并在内存地址下创建了一个新对象,该对象0x02
在我们的Main方法中未引用。
我们的主要方法是使用来自我们在Foo方法中创建的0x01
新地址的实例0x02
!
为了确保将正确的对象传递出去,我们需要告诉C#我们要使用来“编辑”输出,ref
还是要使用来“覆盖”输出out
。
在后台,它们的实现方式相同!
取而代之的传递0x01
给我们的Foo中的方法,我们通过0x03
!其中有一个指向的类的指针0x01
。因此,v = new MyClass()
当我们使用ref
or进行赋值时out
,实际上,我们修改了其值,0x03
然后将其值提取并“替换”到我们的Main方法中以包含适当的值!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句