首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过引用传递值类型

问通过引用传递值类型
EN

Stack Overflow用户
提问于 2014-04-11 14:54:16
回答 5查看 557关注 0票数 1

我正在学习引用类型、值类型、堆栈和堆以及它们之间的区别。

现在我遇到了一些让我难以置信的事情。这里有一个代码示例来说明我的意思

代码语言:javascript
复制
void Main()
{
  int foo = 0;
  PassFoo(ref foo);
  Console.WriteLine(foo);
}
void PassFoo(ref int bar) 
{
  bar = 1;
}

现在,只要我们使用ref关键字,输出就会是1。如果删除ref关键字,则输出将是0。我理解这是因为整数是值类型,当我们按值传递foo时,我们将这个值一点一点地复制到bar,但是当我们添加ref关键字时,我们只是在堆栈上传递foo的内存入口,这也是为什么在本例中我们要更改foo的值。到目前为止我说得对吗?

..。现在说到让我困惑的部分。我对堆栈工作方式的理解是,它只能访问当前运行的堆栈框架。这就是为什么PassFoo不能直接访问foo的原因。我还了解到,值类型存储在声明它们的位置。这就是让我困惑的地方,当我们通过引用传递foo时,我们将foo的内存入口传递给bar,对吗?但是PassFoo()不应该因为它运行在不同的堆栈框架中而无法访问它吗?

我意识到,我可能没有完全正确的理解这是如何工作,所以澄清将是非常感谢的。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-04-11 15:12:02

我对堆栈工作方式的理解是,它只能访问当前运行的堆栈框架。

那是胡说。在遮罩下,方法能够从任何堆栈帧访问内存。C#编译器只是应用约束,以便在大多数情况下,对堆栈上位置的引用不会暴露在该方法的主体之外。这种情况,使用ref关键字,是这种情况的一个例外。一旦进入较低的抽象层,即编译器生成的IL代码,就没有任何约束可以禁止从另一个方法的主体访问堆栈。

你问题的前半部分是对正在发生的事情的有效解释。

票数 3
EN

Stack Overflow用户

发布于 2014-04-11 15:01:49

当您将foo传递到PassFoo中时,您将传递foo所在的地址。因为PassFoo知道foo的值存储在哪里,所以它可以更改该内存地址中的值。PassFoo的堆栈帧仅包含变量的地址。下面是具有指针的等价C代码

代码语言:javascript
复制
#include <stdio.h>

void PassFoo(int* bar)
{
    *bar = 1;
}

int main()
{
    int foo = 0;
    PassFoo(&foo);
    printf("%d", foo);
    return 0;
}
票数 0
EN

Stack Overflow用户

发布于 2014-04-11 15:14:54

如果该方法调用另一个方法,则新方法将在堆栈顶部创建其堆栈框架。通过这种方式,每个新方法都可以在分配给堆栈的内存中分配自己的局部变量,堆栈还用于存储参数并返回方法之间传递的值,这就是为什么存储在bar参数中的foo指针是可见的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23015994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档