2011-07-03 33 views
5

有C中的建议++:“不要返回引用到局部对象”,如下面的“C++入门”引述::永远不会返回对本地对象的引用?

“有了解有关返回引用一个极其重要的一点:永远不会返回到基准的局部变量。

“当一个函数完成,其中,所述局部对象所分配的存储被释放。函数终止后,对本地对象的引用指未定义的内存。考虑下面的函数:。

// 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! 
} 

“,因为它返回到本地对象的引用该函数将在运行时失败当函数结束时,其中保留驻留被释放存储的返回值是指存储器该程序已不再可用。“

问:那么,这是否仍适用于C#?或者随着GC的推出,这并不重要?

+1

我不同意“这一功能会在运行时失败。”它*可能*失败,并且不安全。但在很多情况下,存储将在返回后的一段时间内可用,通常会使这类问题难以调试。 – abelenky

+1

abelenky是正确的;无论如何,任何事情都不会失败。无论如何,存储不是“被释放”的要求。这样做的程序可以按照你想要的方式工作 - 你可能会很幸运 - 或者它可能导致整个系统崩溃,或者它可能会擦除硬盘。它可以做*任何*。有关更多想法,请参阅http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794#6445794。 –

回答

5

不可能在.NET返回局部变量的引用

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

参见:Ref returns and ref locals (Eric Lippert's Blog)

+0

这是有点误导错误。你不能通过引用返回*,但你当然可以返回* a *引用。虽然此引用不会引用本地对象。 –

+0

@Konrad鲁道夫:嗯? Quote:“引用局部变量”。所以像'ref int Foo(){int x = 5; return ref x; }'。这是不可能的。在.NET中没有“本地对象”,只是局部变量包含对由CLR管理的对象的引用。 – dtb

+0

我知道。我仍然认为这可以更清楚地表达出来,因为它很容易误导,而不是仅仅在别处连接。请注意,尽管这种批评,我已upvoted你的答案... –

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

埃里克利珀张贴在这种基准日前与细节回报ref值问题的博客条目:Ref returns and ref locals

+0

谢谢CodeInChaos – athos

相关问题