为什么 C# 不支持引用的返回? [英] Why doesn't C# support the return of references?

查看:13
本文介绍了为什么 C# 不支持引用的返回?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过 .NET 支持引用返回,但 C# 不支持.有什么特殊原因吗?为什么我不能做这样的事情:

I have read that .NET supports return of references, but C# doesn't. Is there a special reason? Why I can't do something like:

static ref int Max(ref int x, ref int y) 
{ 
  if (x > y) 
    return ref x; 
  else 
    return ref y; 
} 

推荐答案

这个问题是 我 2011 年 6 月 23 日的博客.谢谢你的好问题!

This question was the subject of my blog on June 23rd 2011. Thanks for the great question!

C# 团队正在考虑将其用于 C# 7.请参阅 https://github.com/dotnet/roslyn/issues/5233 了解详情.

The C# team is considering this for C# 7. See https://github.com/dotnet/roslyn/issues/5233 for details.

更新:该功能已加入 C# 7!

UPDATE: The feature made it in to C# 7!

你是对的;.NET 确实支持返回 对变量的托管引用的方法..NET 还支持包含对其他变量的托管引用的局部变量.(但是请注意,.NET 不支持包含对其他变量的托管引用的字段数组,因为这会使垃圾收集故事过于复杂.还有对变量的托管引用"类型不能转换为对象,因此不能用作泛型类型或方法的类型参数.)

You are correct; .NET does support methods that return managed references to variables. .NET also supports local variables that contain managed references to other variables. (Note however that .NET does not support fields or arrays that contain managed references to other variables because that overly complicates the garbage collection story. Also the "managed reference to variable" types are not convertible to object, and therefore may not be used as type arguments to generic types or methods.)

评论者RPM1984"出于某种原因要求引用这一事实.RPM1984 我鼓励您阅读 CLI 规范 Partition I 第 8.2.1.1 节托管指针和相关类型"以获取有关 .NET 的此功能的信息.

Commenter "RPM1984" for some reason asked for a citation for this fact. RPM1984 I encourage you to read the CLI specification Partition I Section 8.2.1.1, "Managed pointers and related types" for information about this feature of .NET.

完全有可能创建一个支持这两个功能的 C# 版本.然后你可以做像

It is entirely possible to create a version of C# which supports both these features. You could then do things like

static ref int Max(ref int x, ref int y) 
{ 
  if (x > y) 
    return ref x; 
  else 
    return ref y; 
} 

然后用

int a = 123;
int b = 456; 
ref int c = ref Max(ref a, ref b); 
c += 100;
Console.WriteLine(b); // 556!

我凭经验知道可以构建支持这些功能的 C# 版本因为我已经这样做了.高级程序员,尤其是移植非托管​​ C++ 代码的人,经常要求我们提供更多类似于 C++ 的能力来使用引用做事,而不必费心去实际使用指针和到处固定内存.通过使用托管引用,您可以获得这些好处,而无需支付破坏垃圾收集性能的成本.

I know empirically that it is possible to build a version of C# that supports these features because I have done so. Advanced programmers, particularly people porting unmanaged C++ code, often ask us for more C++-like ability to do things with references without having to get out the big hammer of actually using pointers and pinning memory all over the place. By using managed references you get these benefits without paying the cost of screwing up your garbage collection performance.

我们已经考虑了此功能,并实际实施了足够多的功能以向其他内部团队展示以获取他们的反馈.但是,目前根据我们的研究我们认为该功能没有足够广泛的吸引力或引人注目的用例,无法使其成为真正受支持的语言功能.我们还有其他更高的优先级,可用的时间和精力有限,因此我们不会很快推出此功能.

We have considered this feature, and actually implemented enough of it to show to other internal teams to get their feedback. However at this time based on our research we believe that the feature does not have broad enough appeal or compelling usage cases to make it into a real supported language feature. We have other higher priorities and a limited amount of time and effort available, so we're not going to do this feature any time soon.

此外,正确执行此操作需要对 CLR 进行一些更改.现在,CLR 将 ref 返回方法视为合法无法验证,因为我们没有检测这种情况的检测器:

Also, doing it properly would require some changes to the CLR. Right now the CLR treats ref-returning methods as legal but unverifiable because we do not have a detector that detects this situation:

ref int M1(ref int x)
{
    return ref x;
}

ref int M2()
{
    int y = 123;
    return ref M1(ref y); // Trouble!
}

int M3()
{
    ref int z = ref M2();
    return z;
}

M3 返回 M2 的局部变量的内容,但该变量的生命周期已经结束!可以编写一个检测器来确定 ref-returns 的使用,而这些 ref-returns 显然违反堆栈安全.我们要做的是编写这样一个检测器,如果检测器不能证明堆栈安全,那么我们将不允许在该部分程序中使用 ref 返回.这样做的开发工作量并不大,但要确保我们确实掌握了所有案例,这对测试团队来说是一个很大的负担.这只是将功能成本增加到目前收益不超过成本的另一件事.

M3 returns the contents of M2's local variable, but the lifetime of that variable has ended! It is possible to write a detector that determines uses of ref-returns that clearly do not violate stack safety. What we would do is write such a detector, and if the detector could not prove stack safety, then we would not allow the usage of ref returns in that part of the program. It is not a huge amount of dev work to do so, but it is a lot of burden on the testing teams to make sure that we've really got all the cases. It's just another thing that increases the cost of the feature to the point where right now the benefits do not outweigh the costs.

如果您能向我描述您为什么需要此功能,我将不胜感激.我们从真实客户那里获得的关于他们为什么想要它的信息越多,它就越有可能在某一天融入到产品中.这是一个可爱的小功能,如果有足够的兴趣,我希望能够以某种方式将其提供给客户.

If you can describe for me why it is you want this feature, I would really appreciate that. The more information we have from real customers about why they want it, the more likely it will make it into the product someday. It's a cute little feature and I'd like to be able to get it to customers somehow if there is sufficient interest.

(另见相关问题 是否可以在 C# 中返回对变量的引用?我可以在像 C++ 这样的 C# 函数中使用引用吗?)

(See also related questions Is it Possible to Return a Reference to a Variable in C#? and Can I use a reference inside a C# function like C++?)

这篇关于为什么 C# 不支持引用的返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆