从C ++到C#:永远不会返回对本地对象的引用?

时间:2011-07-03 15:45:49

标签: c# garbage-collection

C ++中有一个建议:“永远不要返回对本地对象的引用”,如下面引用的“C ++ Primer”:

“理解返回引用有一个至关重要的事情:永远不要返回对局部变量的引用。

“函数完成时,释放分配本地对象的存储空间。对函数终止后对本地对象的引用是指未定义的内存。请考虑以下函数:

 // Disaster: Function returns a reference to a local object
 const string &manip(const string& s)
 {
      string ret = s;
      // transform ret in some way
      return ret; // Wrong: Returning reference to a local object!
 }

“此函数在运行时将失败,因为它返回对本地对象的引用。当函数结束时,将释放ret所在的存储。返回值指的是程序不再可用的内存。 “

问题:这仍然适用于C#吗?或者引入GC无关紧要?

2 个答案:

答案 0 :(得分:5)

无法在.NET中返回对局部变量的引用

请参阅:Why doesn't C# support the return of references?

另请参阅:Ref returns and ref locals (Eric Lippert's Blog)

答案 1 :(得分:4)

C#语言不允许这样做。在C#中有两种非常不同的引用:

1)引用类和类似的“引用类型”。由于这些目标始终在堆上分配,因此引用在返回后始终有效。

2)引用局部变量/参数。在CLR中调用managed references。例如:

void DoSomething(ref int i, ref object o)

您不能声明在C#中使用此类引用的返回类型(CLR本身提供了一些受限制的支持)。因为你只能将它们作为参数传递给其他函数,不能将它们存储在字段中,并且不能返回它们,所以在函数返回后不可能保留其中一个。所以再次使用它们是安全的。

基本上在C#中,您只能将它们用于传递引用参数。请注意,参考类型变量ref可以ref object o,但不能引用参考ref ref int i

Eric Lippert几天前发布了一篇关于此类引用的博客文章,详细说明了ref返回值的问题:Ref returns and ref locals