有必要将using与IDisposable对象嵌套吗

本文关键字:IDisposable 对象 嵌套 using | 更新日期: 2023-09-27 18:29:29

是否必须将所有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语句?

有必要将using与IDisposable对象嵌套吗

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

如果没有,那么您可以这样做,至少可以稍微清理一下代码。

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

创建一次性对象的人员/代码/层通常应该负责处理该对象。然而,在某些情况下,情况并非如此,这也没关系。这就成了文档的问题。

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

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

是的,因为您正在实例化实现IDisposable的对象,所以您知道要通过封装在using()或显式Dispose()调用中来处理它。

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

  • 运输服务
  • ReportService
  • FeedService

全部实现CCD_ 11。ReportServiceFeedService都需要在构建阶段传入TransportService的实例。问题是,在ReportService或FeedService的Dispose()中处理TransportService是否正确?不由于传输服务的同一实例可以在两个服务中传递,并且一旦其中一个处理了传输,这也将影响所有服务。

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();
   }
}