【问题标题】:pass ref parameter by value and set it to null按值传递 ref 参数并将其设置为 null
【发布时间】:2011-08-31 21:27:15
【问题描述】:

考虑以下代码片段

Form form2 = new Form();

  test(form2);
  form2.Show();

public void test(Form f)
{
  f = null;
}

由于 f 还持有对 Form2 的“另一个”引用,将 f 设置为 null 应该也将 Form2 设置为 null,但事实并非如此。需要一个很好的解释来理解这一点。

【问题讨论】:

  • 标题中提到的ref在哪里?

标签: reference ref


【解决方案1】:

设置为null 的引用是form2 引用的本地副本。由于引用是按值传递的,这意味着制作一个精确的副本并传递副本,原件保持不变。

这里传递的值可以看作是一个内存地址(这在 VM 中并不完全如此,但它是一个有用且充分的比喻)。

在测试方法中,您将保存此地址副本的变量设置为null。这没有任何进一步的后果。

如果您使用存储在变量中的地址来访问和更改地址所指的实际对象,情况就大不相同了。你在这里改变的是真实的东西,所以在你的局部变量超出范围后所有的改变都会保留。

再退一步:

您可以将变量视为带有朋友(您的对象)地址的纸条。 如果你烧纸(设置变量为null),你的朋友不受影响。 如果你用论文访问地址,送朋友礼物或者打他耳光(在变量后面的对象上调用方法),他肯定会受到影响,你必须承受后果

【讨论】:

  • 同意,那么为什么要设置 f.Text = "Form2";反映在main函数中
  • @Rauld - 用进一步的解释更新了答案,希望它能让事情更清楚
【解决方案2】:

(我假设这是 Java。)

方法参数总是按值传递。这意味着它们的内容总是被复制到一个新变量中。在这种情况下,变量f 的内容(包含对对象的引用)被复制到一个新变量中。当新变量的内容被替换为null 时,原始变量的内容不受影响——它们仍然指向原始对象。

【讨论】:

  • 同意,那么为什么要设置 f.Text = "Form2";反映在 main 函数中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 2022-06-11
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多