作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这个示例代码:
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,我们通过引用v
传递了一个MyClass的实例(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 方法中没有引用它。
我们的主要方法是使用来自地址 0x01
的实例,而不是我们在 Foo 方法中创建的新 0x02
!
为了确保我们传递正确的对象,我们需要告诉 C# 我们想要使用 ref
“编辑”输出或者我们想要使用 out<“覆盖”输出
.
在幕后,它们的实现方式相同!
我们没有将 0x01
传递给我们的 Foo 方法,而是传递了 0x03
!它在 0x01
下有一个指向我们类的指针。因此,当我们使用 ref
或 out
分配 v = new MyClass()
时,实际上我们修改了 的值0x03
然后在我们的 Main 方法中提取并“替换”以包含正确的值!
关于c# - 按引用/值的参数如何在 C# 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65028431/
我是一名优秀的程序员,十分优秀!