为什么我可以 return 引用局部变量的字段
Why can I return a reference to a local variable's field
The documentation on ref returns and ref locals 状态:
The return value must have a lifetime that extends beyond the execution of the method. In other words, it cannot be a local variable in the method that returns it. It can be an instance or static field of a class, or it can be an argument passed to the method. Attempting to return a local variable generates compiler error CS8168, "Cannot return local 'obj' by reference because it is not a ref local."
我以为我明白了。我想如果我 return 编辑了对局部变量的引用,那么该变量可能会被收集,因此我的引用不再引用变量。
但是,我今天了解到我可以创建一个局部变量,然后 return 对该局部变量上的字段的引用。举例说明:
using System;
namespace IAmConfused
{
class Program
{
static void Main(string[] args)
{
var foo = new Foo();
ref int barInt = ref foo.GetInt();
Console.WriteLine(barInt); //Outputs 123
barInt = 354;
Console.WriteLine(barInt); //Outputs 354
}
}
public class Foo
{
public ref int GetInt()
{
// int x = 123;
// return ref x; //CS8168
var bar = new Bar(123);
return ref bar.Value;
}
class Bar
{
public Bar(int v)
{
Value = v;
}
public int Value;
}
}
}
这与 return本地人有什么不同?局部变量 bar
可能会在 GetInt
return 秒后被收集,对吧?那么如果发生这种情况,barInt
引用的是什么?
我已经尝试了 C#
版本 7.0、7.1、7.2 和 7.3,它适用于所有版本。
考虑这个代码示例:
void Foo()
{
object a;
int b;
}
这两个变量都保存在堆栈中。是的,它们确实是,甚至是对象。变量 a
是指向对象的指针,而不是对象本身,并且该指针确实是堆栈上的局部变量。
因此,如果您 return 对其中任何一个的引用,它将是对堆栈中某个变量的引用。当调用 returns 时,堆栈当然会被覆盖,这就是为什么你不能引用 return 本地的原因。
另一方面,考虑这个例子:
class Bar
{
public int SomeInteger;
}
void Foo()
{
Bar c = new Bar();
}
在这种情况下,c
也保存在堆栈中。但是它引用的对象在堆上,它的字段 SomeInteger
也是如此。所以你可以安全地 return 引用 SomeInteger
因为它存在于堆上并且当方法 returns.
时堆不会被覆盖
The documentation on ref returns and ref locals 状态:
The return value must have a lifetime that extends beyond the execution of the method. In other words, it cannot be a local variable in the method that returns it. It can be an instance or static field of a class, or it can be an argument passed to the method. Attempting to return a local variable generates compiler error CS8168, "Cannot return local 'obj' by reference because it is not a ref local."
我以为我明白了。我想如果我 return 编辑了对局部变量的引用,那么该变量可能会被收集,因此我的引用不再引用变量。
但是,我今天了解到我可以创建一个局部变量,然后 return 对该局部变量上的字段的引用。举例说明:
using System;
namespace IAmConfused
{
class Program
{
static void Main(string[] args)
{
var foo = new Foo();
ref int barInt = ref foo.GetInt();
Console.WriteLine(barInt); //Outputs 123
barInt = 354;
Console.WriteLine(barInt); //Outputs 354
}
}
public class Foo
{
public ref int GetInt()
{
// int x = 123;
// return ref x; //CS8168
var bar = new Bar(123);
return ref bar.Value;
}
class Bar
{
public Bar(int v)
{
Value = v;
}
public int Value;
}
}
}
这与 return本地人有什么不同?局部变量 bar
可能会在 GetInt
return 秒后被收集,对吧?那么如果发生这种情况,barInt
引用的是什么?
我已经尝试了 C#
版本 7.0、7.1、7.2 和 7.3,它适用于所有版本。
考虑这个代码示例:
void Foo()
{
object a;
int b;
}
这两个变量都保存在堆栈中。是的,它们确实是,甚至是对象。变量 a
是指向对象的指针,而不是对象本身,并且该指针确实是堆栈上的局部变量。
因此,如果您 return 对其中任何一个的引用,它将是对堆栈中某个变量的引用。当调用 returns 时,堆栈当然会被覆盖,这就是为什么你不能引用 return 本地的原因。
另一方面,考虑这个例子:
class Bar
{
public int SomeInteger;
}
void Foo()
{
Bar c = new Bar();
}
在这种情况下,c
也保存在堆栈中。但是它引用的对象在堆上,它的字段 SomeInteger
也是如此。所以你可以安全地 return 引用 SomeInteger
因为它存在于堆上并且当方法 returns.