C# using语句是否保留对其接收的对象的引用?

C# using语句是否保留对其接收的对象的引用?,c#,reference,garbage-collection,using,idisposable,C#,Reference,Garbage Collection,Using,Idisposable,当使用这样的“using”语句时: using (Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker()) { ... using (new MessageGenerator()) { Console.WriteLine("Please give me lots of reputation."); } 而不是 using (var lt = Global.Instance.BusyLif

当使用这样的“using”语句时:

  using (Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker())
  {
    ...
using (new MessageGenerator())
{
    Console.WriteLine("Please give me lots of reputation.");
}
而不是

  using (var lt = Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker())
  {
    ...
“using”语句是否会保留对返回对象的引用,以确保不会过早地对其进行垃圾收集?。。。是否没有为其声明显式变量(第一个示例代码)

第二个示例代码显然很好,但第一个呢


任何文档和/或对信息的引用都将不胜感激。

是的,保留一个真实的引用,以便在最后调用
Dispose
方法。当您不明确需要使用块访问
内的一次性对象时,此模式通常用于在处置中执行某种“副作用”。例如,在Razor
中,使用(Html.BeginForm){…}
允许处理返回的对象,以在末尾输出
标记

C#中的一个简单示例是:

public class MessageGenerator : IDisposable
{
    public MessageGenerator()
    {
        Console.WriteLine("To whom it may concern,");
    }
    
    public void Dispose()
    {
        Console.WriteLine("Thanks and goodbye.");
    }
}
用法如下:

  using (Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker())
  {
    ...
using (new MessageGenerator())
{
    Console.WriteLine("Please give me lots of reputation.");
}
将给出如下输出:

  using (Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker())
  {
    ...
using (new MessageGenerator())
{
    Console.WriteLine("Please give me lots of reputation.");
}
与之相关的人

请给我一个好名声

谢谢,再见


回答问题的文档和参考部分:

附注:

using语句以正确的方式调用对象上的方法,并且(当您如前所示使用它时),它还会导致对象本身在被调用后立即超出范围。在
using
块中,对象是只读的,不能修改或重新分配

就第一个代码块的语法而言,具有以下语法:

使用_语句
:“使用”(“资源获取”)嵌入的语句
;
资源获取
:局部变量声明
|表情
;
在这里,您将注意到
resource\u acquisition
可以是一个局部变量声明,也可以是一个表达式,这是您的第一个代码块使用的。代码如下:

using (File.OpenRead("Test.txt")){}
…转化为:

FileStream fileStream = File.OpenRead("Test.txt");
try
{
}
finally
{
    if (fileStream != null)
    {
        ((IDisposable)fileStream).Dispose();
    }
}

声明了一个变量,该变量保存对所用对象的引用。

Yes,否则它将无法对其调用
Dispose
。Yes,引用
lt
仅供您在块中使用。如果你不需要使用它,你不需要声明它。使用块将以任意方式处理对象。这是一种您偶尔会看到的模式,在该模式中,仅为在Dispose()方法中撤消的临时副作用创建对象。例如,我们有一个名为WaitCursor的类,该类在构造函数中将游标设置为wait游标,并在Dispose()中将其恢复为以前的状态。是的,是一个真正的引用。正如Ed所建议的,这种模式经常被用来做一些有副作用的事情。例如,在Razor
中,使用(Html.BeginForm){…}
允许处理返回的对象,以在末尾输出
标记。我调用了:使用(Global.Instance.busylfetrackerstack.GetNewLifeTracker()){GC.Collect();GC.WaitForPendingFinalizers();}并调用了“Dispose”。非常感谢。。。是的,我知道,我应该在问我的问题之前核实一下。。。很抱歉谢谢大卫,我最终决定和异教徒猴子一起去,因为我得到了解释这种行为的确切文件。此外,我认为您需要强制垃圾收集器收集到“using”语句块中,以防止这种行为。但是非常感谢你。我感觉好多了,因为我确实经常在代码中使用模式而不分配任何变量(使用“using”)。不,这不是关于GC,而是关于调用
Dispose
using
语句实际上只是围绕
try/
finally`块的语法糖分。GC发生在一个未指定的时间,我担心我的一次性对象可能在到达finally块和Dispose方法之前被垃圾收集。这就是为什么在我看来,强制GC收集是确保正确行为的必要条件。无论是样品还是文件都可以证明这一点。异教徒找到了正确的文档。不,强制GC根本不需要。你得到了我要的准确文档。一个强制GB在using块内收集的示例也是一个很好的答案。谢谢非常感谢您的示例(来自SharpLab的示例)。这是一个难以置信的工具,我不知道它的存在。非常感谢你!!!!!!!!