有必要将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;
}
我能指望Stream
和StreamReader
都被处理吗?还是必须使用两个using
语句?
是的,您可以 ,但这是因为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。ReportService
和FeedService
都需要在构建阶段传入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();
}
}