using语句是否保留对其收到的对象的引用?

时间:2019-06-04 15:32:23

标签: c# reference garbage-collection using idisposable

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

import matplotlib.pyplot as plt
import matplotlib.ticker as tck

fig, ax = plt.subplots()
plt.plot([1,2])

ax.yaxis.set_minor_locator(tck.AutoMinorLocator())

代替

  using (Global.Instance.BusyLifeTrackerStack.GetNewLifeTracker())
  {
    ...

“ using”语句会保留对返回对象的引用,以确保不会更早地对其进行垃圾回收吗?...是否没有为其声明任何显式变量(第一个示例代码)? / p>

第二个示例代码显然可以,但是第一个示例代码?

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

3 个答案:

答案 0 :(得分:3)

是的,保留了真实的引用,以便可以在最后调用Dispose方法。当您不需要显式访问using块内的一次性对象时,该模式通常用于在处置中执行某种“副作用”。例如,在Razor中,using(Html.BeginForm){...}允许处理返回的对象以在最后输出</form>标签。

在C#中一个简单的例子是:

public class MessageGenerator : IDisposable
{
    public MessageGenerator()
    {
        Console.WriteLine("To whom it may concern,");
    }

    public void Dispose()
    {
        Console.WriteLine("Thanks and goodbye.");
    }
}

和这样的用法:

using (new MessageGenerator())
{
    Console.WriteLine("Please give me lots of reputation.");
}

将给出这样的输出:

  

可能与之相关的人

     

请给我很多声誉

     

谢谢,再见。

答案 1 :(得分:1)

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

documentation for the using statement注释:

  

using语句以正确的方式在对象上调用Dispose方法,并且(如前所述,当您使用它时)它也会导致对象本身在{{3}时超出范围} 叫做。在using块中,该对象为只读对象,无法修改或重新分配。

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

  
using_statement
    : 'using' '(' resource_acquisition ')' embedded_statement
    ;

resource_acquisition
    : local_variable_declaration
    | expression
    ;

在这里,您会注意到resource_acquisition可以是局部变量声明或表达式,这是您的第一个代码块使用的语言。

答案 2 :(得分:1)

这里是an example编译器在后台执行的操作。下面的代码:

using (File.OpenRead("Test.txt")){}

...被转换为:

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

声明一个变量,其中包含对所用对象的引用。