C# 关于在C中哪些类型的对象可以“通过引用返回”的问题
我在看书。 至于通过引用返回,它说 由于对象生命周期的原因,按引用返回有两个重要的限制:对象引用在仍被引用时不应被垃圾收集,当它们不再有任何引用时不应消耗内存。要强制执行这些限制,只能从引用返回函数返回以下内容: •对字段或数组元素的引用 •其他参考返回属性或功能 •作为参数传入by reference返回函数的引用 我做了一些实验,结果肯定如书中所说C# 关于在C中哪些类型的对象可以“通过引用返回”的问题,c#,ref,C#,Ref,我在看书。 至于通过引用返回,它说 由于对象生命周期的原因,按引用返回有两个重要的限制:对象引用在仍被引用时不应被垃圾收集,当它们不再有任何引用时不应消耗内存。要强制执行这些限制,只能从引用返回函数返回以下内容: •对字段或数组元素的引用 •其他参考返回属性或功能 •作为参数传入by reference返回函数的引用 我做了一些实验,结果肯定如书中所说 namespace App { public class App { static void Main()
namespace App
{
public class App
{
static void Main()
{
}
class Test
{
public int x;
}
ref int RefReturn()
{
int[] a = { 1, 2 };
return ref a[0];
}
ref int RefReturn2()
{
Test t = new Test();
return ref t.x;
}
ref int RefReturnError()
{
int a = 1;
return ref a; //Error
}
ref Test RefReturnError2()
{
Test t = new Test();
return ref t; //Error
}
}
}
我不太明白这一点。
这三种可以在书中引用,为什么这三种?
例如,我可以返回类的字段,但不能返回类。
代码中的ref int RefReturn2和ref Test RefReturnError2
我认为应该是关于C中的对象生命周期和垃圾收集的问题,我对此不太了解
我还想知道使用参照退货的典型情况。
我认为典型情况也有助于理解。局部变量与方法具有相同的生存期,变量本身的内存位置在堆栈上 因此,在方法返回后,变量int a或Test t都不存在 但是[0]和t.x存在于存储在堆内存中的对象中。当方法返回时,它们仍然存在,因为它们位于堆栈之外 举个例子吧。为什么use希望使用ref local或ref return?定义链表时如何 内部类节点 T:在哪里上课 { 内部T项目; 内部节点下一步; } 公共类链接列表 T:在哪里上课 { 私有节点根; 私有ref节点FindFunc比较 { ref var ret=参考根; 而ret!=null&&comparisonret.Item ret=参考ret.Next; 返回ref ret; } public void InsertT newItem,Func比较 { ref var位置=ref Findcomparison; 位置=新节点 { Item=newItem, 下一个=位置。下一个 }; } } Find返回对节点字段的引用,然后可以将新节点分配给该字段。因此,您可以处理分配给根或某个节点的操作。接下来,无需两种特殊情况。托管引用规则ref的关键要点是:托管引用不能指向局部变量,或者在结构的情况下不能指向局部变量的一部分,因为该引用可以超过其指向的位置的寿命。它必须指向非堆栈位置 让我们一个接一个地看每个版本 ref int RefReturn { int[]a={1,2}; 返回参考a[0]; } 在上面的示例中,返回的引用指向数组的内部,而不是指向局部变量。数组的内部实际上是堆对象的字段。数组将超过函数的生命周期 ref int RefReturn2 { 试验t=新试验; 返回参考t.x; } 在本例中,Test是引用类型,因此存在于堆中。引用指向t中包含的对象的字段x,它也存在于堆中。t是局部变量这一事实无关紧要,参考文献并不指向t ref int RefReturnError { INTA=1; 返回ref a;//错误 } 在这种情况下,引用指向局部变量的实际位置,该位置位于堆栈上,并且该位置将在函数结束时消失 请注意,当引用结构的字段时,当结构的位置是局部变量时,同样的问题也会出现 参考int RefReturnError1A { MyStruct a=新MyStruct; 返回ref a.x;//错误 } 参考测试RefReturnError2 { 试验t=新试验; 返回ref t;//错误 } 在本例中,尽管t是一个引用类型,并且它本身指向一个堆对象,但我们的引用并没有指向t所指向的对象。它指向包含该对象引用的t本身的位置 请注意,由于不同的原因,不允许引用已装箱的结构:由于C的取消装箱规则,从逻辑上来说,取消装箱将创建一个副本,因此您无法就地更改它。直接在IL或C++/CLI中编码您可以完全验证地执行以下等效操作: ref int RefReturnBox { 对象a=对象1; return ref inta;//CS0445:无法修改取消装箱转换的结果 }
你到底不明白什么?你所说的“不上课”是什么意思?你是指代码中的某一行吗?你到底指的是什么
你明白吗我不明白这本书的意思,这三种可以通过引用返回。这很难记住。这本书说这是关于对象生命周期的,但我不明白为什么。我想从RefReturn2工作的原因开始,但RefReturnError2失败了。我不使用Ref返回和Ref局部变量,因为我相信它会产生复杂的代码;但同时,我会对这两种方法的不同感兴趣。你说的“但不是”类是什么意思?您是指代码中的特定行吗?-是的,我指的是代码中的ref int RefReturn2和ref Test RefReturnError2函数。meh-我不喜欢这个答案,因为它没有解释RefReturnError2是如何工作的。测试t在堆上。它不是值类型。就像在RefReturn2中一样。@Andy否,只有t存储引用的测试对象在堆上。如果您希望通过引用返回该测试对象,则返回t;做返回参考t;如果有效,将通过引用返回局部变量t。封闭方法返回后,局部变量不存在。回答得好。快速提问-最后一句:它指向t的位置-你的话存储在堆栈上,对吗?这就是为什么它不能工作,因为堆栈在返回时被销毁。正确,t的位置不是t指向的对象存在于堆栈上