C#out-parameter

时间:2011-09-19 19:31:03

标签: c# parameters heap out

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

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

和第二个:

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

第二个代码段是否属实是危险的,因为x现在有一个对本地y的引用,退出foo后可能已经死了?

为什么我们一般要使用“新”?

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

4 个答案:

答案 0 :(得分:4)

让我们暂时假设第二个片段是

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

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

考虑到编译片段,将out变量分配给本地声明和初始化的对象不会有任何危险。 classA指向的y对象以及分配给x的{​​{1}}对象将保持活动状态,直到x超出声明/使用范围的范围。

答案 1 :(得分:2)

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

鉴于你在C#中的第二个例子:

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

无论如何,这可能无法编译,因为永远不会为y分配值。

答案 2 :(得分:1)

  

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

是真的吗?

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

答案 3 :(得分:1)

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