【问题标题】:Returning from method disposes corectly the object? [closed]从正确处理对象的方法返回? [关闭]
【发布时间】:2012-09-29 16:19:38
【问题描述】:

如果你使用using 方法而不是让我们说FileStream.Close();,类会正确处理吗?

private static string GetString()
{
    using(FileStream fs = new FileStream("path", FileMode.Open))
    using(StreamReader sr = new StreamReader(fs))
    {
         return sr.ReadToEnd();
    }
}

相当于:

private static string GetString()
{
    string toReturn = "";           

    FileStream fs = new FileStream("path", FileMode.Open)
    StreamReader sr = new StreamReader(fs)

    toReturn = sr.ReadToEnd();

    sr.Close();
    fs.Close();

    return toReturn;
}

或到:

private static string GetString()
{
    FileStream fs;
    StreamReader sr;

    try
    {
        string toReturn = "";          

        fs = new FileStream("path", FileMode.Open)
        sr = new StreamReader(fs)

        toReturn = sr.ReadToEnd();

        sr.Close();
        fs.Close();

        return toReturn;
    }
    finally
    {
       if(sr != null)
           sr.Close();

       if(fs != null)
           fs.Close();
    }
}

【问题讨论】:

标签: c# .net idisposable using-statement try-finally


【解决方案1】:

using 语句生成的代码与您的第二个示例非常相似(最大的区别是它调用IDisposable.Dispose 而不是Close)。无论方法是通过return 退出还是抛出异常,它都会正确处理对象。

如果您好奇,这是没有 usings 的 C# 代码,它编译为与您使用 usings 的示例相同的 IL:

private static string GetString()
{
    FileStream fs = new FileStream("path", FileMode.Open);
    try
    {
        StreamReader sr = new StreamReader(fs);
        try
        {
            return sr.ReadToEnd();
        }
        finally
        {
            if (sr != null)
                ((IDisposable)sr).Dispose();
        }
    }
    finally
    {
        if (fs != null)
            ((IDisposable)fs).Dispose();
    }
}

【讨论】:

  • 它不是这样编译的——声明在try之外,赋值在里面(否则,没有办法进入tryfs非空,在在这种情况下为什么要检查finally 中的非空值。
  • 我一定不同意。我正在查看 ILSpy 中的每个反编译。 ilspy.net 唯一的区别是一些 nop 操作(奇怪的是,我正在使用 VS2012 以发布模式构建;但这无关紧要)。包含非空检查是因为您可以执行 using (FileStream fs = null) 或更可能的是 using (var fs = GetSomething()),这可能会返回空值。
【解决方案2】:

看看using声明:

http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.110).aspx

应该相当于:

FileStream fs = null;

try
{
    fs = new FileStream("path", FileMode.Open);
    StreamReader sr = null;
    try
    {
        sr = new StreamReader(fs);
        toReturn = sr.ReadToEnd();
        return toReturn;
    }
    finally
    {
       if(sr != null)
           sr.Dispose();
    }
}
finally
{
    if(fs != null)
        fs.Dispose();
}

Dispose方法内部,它会调用Close流。

【讨论】:

  • 它不是这样编译的——声明在try之外,赋值在里面(否则,没有办法进入tryfs非空,在在这种情况下为什么要检查finally 中的非空值。
  • @Damien_The_Unbeliever:没错
【解决方案3】:

如果它实现了IDisposable,它将在退出使用块时正确关闭。

【讨论】:

    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 2010-12-23
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 2016-03-19
    • 2015-04-20
    相关资源
    最近更新 更多