是否有必要使用IDisposable对象嵌套使用?

时间:2012-03-30 19:34:49

标签: c#

我是否必须在IDisposable语句中包装所有using(){}个对象,即使我只是将它们传递给另一个?例如,在以下方法中:

public static string ReadResponse(HttpWebResponse response)
{
    string resp = null;
    using (Stream responseStream = response.GetResponseStream())
    {
        using (StreamReader responseReader = new StreamReader(responseStream))
        {
            resp = responseReader.ReadToEnd();
        }
    }
    return resp;
}

我可以将此合并为只有一个using,如下所示:

public static string ReadResponse(HttpWebResponse response)
{
    string resp = null;
    using (StreamReader reader = new StreamReader(response.GetResponseStream()))
    {
        resp = reader.ReadToEnd();
    }
    return resp;
}

我可以依靠被处置的StreamStreamReader吗?或者我必须使用两个using语句吗?

3 个答案:

答案 0 :(得分:12)

是的,您可以 ,但这是因为StreamReader构造函数文档特别说:“StreamReader对象在调用StreamReader.Dispose时调用提供的Stream对象上的Dispose。 “

如果没有,那么你可以做这样的事情来至少清理一下代码。

using (Stream responseStream = response.GetResponseStream())
using (StreamReader responseReader = new StreamReader(responseStream))
{
    resp = responseReader.ReadToEnd();
}

答案 1 :(得分:3)

创建一次性对象的人/代码/层通常应负责处理对象。但是,有些情况可能会出现这种情况并非如此。它成为文档的一个问题。

答案 2 :(得分:2)

我发现这个问题比using语句嵌套的简单问题更广泛,这是一个非常有趣的应用程序设计问题。

  

我是否必须将所有IDisposable对象包装在using(){}语句中,   即使我只是把一个传递给另一个人?

是的,因为您正在实例化实现IDisposable的对象 - 您知道通过包装using()或显式Dispose()调用来处置它。

这背后的原因很简单,想象下一个场景:你有以下实体

  • TransportService
  • ReportService的
  • FeedService

所有工具IDisposableReportServiceFeedService都需要在构建阶段传递TransportService的实例。问题是 - 在ReportService或FeedService的TransportService中处理Dispose()是否正确?没有!因为同一个传输服务实例可以在两个服务中传递,一旦处理传输一个传输 - 这也将影响所有服务。

public sealed class ReportService : IDisposable
{       
   private readonly ITransportService transportService;

   public ReportService(ITransportService transportService)
   {
       this.transportService = transportService;
   }

   public Dispose()
   {
      // ReportService should not dispose objects
      // passed in since they could be used by other classes as well
      // DO NOT: transportService.Dispose();
   }
}