c# - C# 7.0 中的 Ref 返回限制

标签 c# c#-7.0

我试图理解以下摘自官方博客文章的摘录,该文章介绍了 C# 7.0 中与引用返回有关的新功能。

  1. You can only return refs that are “safe to return”: Ones that were passed to you, and ones that point into fields in objects.

  2. Ref locals are initialized to a certain storage location, and cannot be mutated to point to another.

遗憾的是,该博文没有给出任何代码示例。如果有人可以通过实际示例和解释进一步阐明以粗体突出显示的限制,我们将不胜感激。

提前致谢。

最佳答案

您得到了一些澄清限制的答案,但没有说明限制背后的原因。

限制背后的原因是我们绝不能允许死变量的别名。如果你在一个普通方法中有一个普通的局部变量,并且你返回一个 ref 给它,那么在使用 ref 时局部变量已经死了。

现在,有人可能会指出 ref 返回的局部变量可以提升到闭包类的字段。是的,那会解决问题。但该特性的重点是让开发者编写高性能的接近机器的低成 native 制,并自动提升到闭包——然后承担收集压力等负担——工作反对那个目标。

事情可能会变得有些棘手。考虑:

ref int X(ref int y) { return ref y; }
ref int Z( )
{
  int z = 123;
  return ref X(ref z);
}

在这里,我们以偷偷摸摸的方式将引用返回给本地 z!这也必须是非法的。但现在考虑一下:

ref double X(ref int y) { return ref whatever; }
ref double Z( )
{
  int z = 123;
  return ref X(ref z);
}

现在我们可以知道返回的 ref 不是 z 的 ref。那么,如果传入的 refs 类型与返回的 refs 类型都不同,我们能说这是合法的吗?

这个呢?

struct S { public int s; }
ref int X(ref S y) { return ref y.s; }
ref int Z( )
{
  S z = default(S);
  return ref X(ref z);
}

现在我们又一次返回了一个死变量的引用。

当我们第一次设计此功能时(在 2010 年 IIRC 中),有许多复杂的建议来处理这些情况,但我最喜欢的建议只是“让所有这些都是非法的”。您不会返回通过引用返回方法返回的引用,即使它不可能死掉。

我不知道 C# 7 团队最终实现了什么规则。

关于c# - C# 7.0 中的 Ref 返回限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42875161/

相关文章:

c# - 如何从 C# 使用 C++ dll

c# - 如何使用应存在的2个字段编写Nest查询

c# - 如何使用C#获取系统的MAC ID

c# - Asp.Net Web API 未从 Angular 接收 Post 数据

c# - 如何在 switch 语句中使用 c# 元组值类型

c# - 内联变量声明不编译

c# - 当将整数视为对象并进行比较时,为什么整数不会提升为 double ?

c# - 是否可以解构出 ValueTuple 参数?

c# - 在 select 语句中使用命名元组

c# - 类型 T 的表达式不能由类型 X 的模式处理