C# 为什么我可以返回对局部变量的引用';s场

C# 为什么我可以返回对局部变量的引用';s场,c#,c#-7.0,C#,C# 7.0,国家: 返回值的生存期必须超过方法的执行时间。换句话说,它不能是返回它的方法中的局部变量。它可以是类的实例或静态字段,也可以是传递给方法的参数。尝试返回局部变量会生成编译器错误CS8168,“无法通过引用返回局部'obj',因为它不是局部引用。” 我想我明白了。我想如果我返回一个对局部变量的引用,那么该变量可能会被收集,因此我的引用不再引用变量 但是,我今天学到了,我可以创建一个局部变量,然后返回对该局部变量上字段的引用。举例说明: 使用系统; 命名空间IAMMAID { 班级计划 { 静态vo

国家:

返回值的生存期必须超过方法的执行时间。换句话说,它不能是返回它的方法中的局部变量。它可以是类的实例或静态字段,也可以是传递给方法的参数。尝试返回局部变量会生成编译器错误CS8168,“无法通过引用返回局部'obj',因为它不是局部引用。”

我想我明白了。我想如果我返回一个对局部变量的引用,那么该变量可能会被收集,因此我的引用不再引用变量

但是,我今天学到了,我可以创建一个局部变量,然后返回对该局部变量上字段的引用。举例说明:

使用系统;
命名空间IAMMAID
{
班级计划
{
静态void Main(字符串[]参数)
{
var foo=new foo();
ref int barInt=ref foo.GetInt();
Console.WriteLine(barInt);//输出123
barInt=354;
Console.WriteLine(barInt);//输出354
}
}
公开课Foo
{
公共引用int GetInt()
{
//int x=123;
//返回ref x;//CS8168
var bar=新的bar(123);
返回参考条值;
}
分类栏
{
公共酒吧(INTV)
{
值=v;
}
公共价值观;
}
}
}
这与仅仅返回本地文件有什么不同?局部变量
bar
可能在
GetInt
返回后收集,对吗?那么,如果发生这种情况,
barInt
引用是什么呢


我尝试了
C#
版本7.0、7.1、7.2和7.3,它们都可以使用。

考虑以下代码示例:

void Foo()
{
    object a;
    int b;
}
这两个变量都保存在堆栈上。是的,它们确实是,甚至是物体。变量
a
是指向对象的指针,而不是对象本身,该指针实际上是堆栈上的局部变量

因此,如果您返回对其中任何一个的引用,它将是对堆栈上某个变量的引用。当调用返回时,堆栈当然会被覆盖,这就是为什么不能返回一个local

另一方面,考虑这个例子:

class Bar
{
    public int SomeInteger;
}

void Foo()
{
    Bar c = new Bar();
}

在这种情况下,
c
也保存在堆栈上。但是它引用的对象和它的字段
SomeInteger
都在堆上。因此,您可以安全地返回对
SomeInteger
的引用,因为它存在于堆上,并且当方法返回时堆不会被覆盖。

您返回的不是变量
bar
,而是其他变量(
bar.Value
)。当你试图返回一个局部变量时会发生什么?如果我试图返回一个局部变量,我会得到一个编译器错误。CS8168,如文档所述。我不知道为什么在局部变量上返回字段会有不同的行为。在这两种情况下,我返回的内容似乎都没有超出方法执行范围的生存期。它不是“局部变量上的字段”,而是“驻留在堆内存中的对象中的字段”。当您尝试使用结构而不是类时会发生什么?更改为结构也会导致CS8168。堆栈不会被覆盖。移动堆栈指针以回收内存。否则答案很好。当然,我猜它是无效的,直到下一个方法调用,此时它被覆盖。我想你明白了。也许它被覆盖了。这取决于程序中还发生了什么:-)