1

以下两个代码片段有什么区别?

public void foo(out classA x)
{
    y = new classA();
    x = y;
}

第二个:

public void foo(out classA x)
{
    classA y;
    x = y;
}

第二个片段是否真的很危险,因为x现在有一个对这个 local 的引用y,它在 exit 之后可能已经死了foo

为什么我们通常必须使用“新”?

我有点困惑,因为在 C++ 中,如果x在第二个片段中是一个指针,那么该语句x = y甚至不会编译,因为y它不是一个指针。

4

4 回答 4

4

让我们假设第二个片段是

public void foo(out classA x)
{
  classA y = new classA();
  x = y;
}

您编写的代码段根本无法在 C# 中编译。y必须先分配。该行classA y;不会classA像在 C++ 中那样在堆栈上创建实例。它只是声明了一个y类型为 的变量classA

考虑到编译片段,将out变量分配给本地声明和初始化的对象无论如何都不危险。指向并分配给的classA对象将保持活动状态,直到超出声明/使用的范围。yxx

于 2011-09-19T19:34:22.853 回答
2

我认为您的困惑是,在 C++ 中,第二个示例将返回对堆栈分配对象的引用。这在 C# 中不会发生。

鉴于您在 C# 中的第二个示例:

public void foo(out classA x)
{
  classA y;  // Doesn't allocate an object
  x = y;
}

无论如何,这可能不会编译,因为y从未分配过值。

于 2011-09-19T19:40:32.070 回答
1

第二个片段是否真的很危险[...]

不在 C# 中;您正在考虑像 C 或 C++ 这样的本地语言,它们允许使用指向局部变量的指针。在 C# 中,一切(在合理范围内)都是对托管对象的引用。一切基本上都在堆上。

于 2011-09-19T19:38:43.423 回答
1

这并不危险,因为除非在方法返回或退出之前为所有“out”参数提供定义,否则代码将无法编译。

于 2011-09-19T19:39:12.570 回答