gpt4 book ai didi

c# - 按引用/值的参数如何在 C# 中工作

转载 作者:行者123 更新时间:2023-12-04 00:52:57 25 4
gpt4 key购买 nike

我有这个示例代码:

    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.

Step1

我们看到我们进入了Foo,我们通过引用v传递了一个MyClass的实例(C#中的类实例默认是通过引用传递的)

在内存中,我们会看到这样的东西:

v = 0x01; //0x01 - is a simple representation of a pointer that we passed
v.Value = 1;

接下来,我们跨过一步,我们看到我们更改了引用中的值 Value。 step 2

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 方法中没有引用它。

step3

我们的主要方法是使用来自地址 0x01 的实例,而不是我们在 Foo 方法中创建的新 0x02!

为了确保我们传递正确的对象,我们需要告诉 C# 我们想要使用 ref“编辑”输出或者我们想要使用 out<“覆盖”输出.

在幕后,它们的实现方式相同!

我们没有将 0x01 传递给我们的 Foo 方法,而是传递了 0x03!它在 0x01 下有一个指向我们类的指针。因此,当我们使用 refout 分配 v = new MyClass() 时,实际上我们修改了 的值0x03 然后在我们的 Main 方法中提取并“替换”以包含正确的值!

关于c# - 按引用/值的参数如何在 C# 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65028431/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com