【问题标题】:c# pass by valuec# 按值传递
【发布时间】:2010-06-27 08:02:02
【问题描述】:

我只是想举个例子:

public void main()
{

   int x = 1;

   Foo(x);
}

public void Foo(int y)
{
    y = 5;
}

我们知道 C# 参数是按值类型传递的。这是否意味着在上面的示例中,我在堆栈上有 2 个副本,一个用于 x,一个用于 y?

【问题讨论】:

  • 很抱歉,上面的代码在第一种情况下无法编译:p

标签: c#


【解决方案1】:

是的,堆栈上会有两个自变量。它们也将位于两个不同的堆栈帧中——一个用于main,一个用于foo(假设没有内联)。当Foo 返回时,x 的值仍然是 1,而不是 5。

事实上,在 C# 中,参数总是默认按值传递,对于引用类型和值类型都是如此。唯一的区别是对于引用类型,参数值一个引用——而不是对象本身。

请参阅我的article on parameter passing 了解更多详情。

请注意,堆栈上的实际行为是implementation detail:C# 编译器必须确保程序的行为符合规范中的定义,但这并不强制要求堆栈或堆行为。所以x 确实必须在你的代码末尾有值 1,但是一个有效的 C# 编译器可以xy都放在堆。

【讨论】:

  • 感谢乔恩,我感到很受追捧,伟大的乔恩·斯基特。等不及你即将出版的书了。关于内联的问题,编译器如何决定是否内联方法调用?
  • 或者他们既不能在栈也不能在堆上; (1) 生成将其放入寄存器的代码,或 (2) 生成 根本不生成代码 是完全合理的,因为该代码什么都不做,也没有副作用,可以在jit 时间。
  • @ash2010:C# 编译器没有内联任何内容。 JIT 编译器执行内联,在 CLR v4 中,它会告诉您何时决定执行内联! blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/…
【解决方案2】:

你理解正确 - x 的值将被放入堆栈中 main 函数的堆栈中,y 的值将被放入堆栈中 @987654324 的堆栈中@。

【讨论】:

    【解决方案3】:

    要了解更多细节,您还需要了解值参数是如何传递的。 Foo 中的 y 不影响 Main 中的 x 的原因是它们位于不同的堆栈帧中。有关传递值​​类型参数的更多详细信息是HERE

    【讨论】:

    • 我不能说我很喜欢那个页面。例如,它专门调用值类型,并说:“因此,将值类型变量传递给方法意味着将变量的副本传递给方法。”对于引用类型也是如此。 (好吧,假设它表示变量 value 的副本 - 它肯定不是在复制变量本身。)只是对于引用类型变量,值是引用。默认情况下仍会复制该值...
    猜你喜欢
    • 2023-03-02
    • 2014-10-03
    • 2012-07-29
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    • 2011-05-08
    相关资源
    最近更新 更多