我是否必须在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
语句吗?
答案 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()
调用来处置它。
这背后的原因很简单,想象下一个场景:你有以下实体
所有工具IDisposable
。 ReportService
和FeedService
都需要在构建阶段传递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();
}
}