Gho*_*der 25 c# idisposable using
有时我需要在函数中使用几个一次性对象.最常见的情况是使用StreamReader和StreamWriter,但有时它甚至比这更多.
嵌套使用语句快速加起来并且看起来很难看.为了解决这个问题,我创建了一个小类,它收集IDisposable对象并在它本身被处置时处理它们.
public class MultiDispose : HashSet<IDisposable>, IDisposable
{
public MultiDispose(params IDisposable[] objectsToDispose)
{
foreach (IDisposable d in objectsToDispose)
{
this.Add(d);
}
}
public T Add<T>(T obj) where T : IDisposable
{
base.Add(obj);
return obj;
}
public void DisposeObject(IDisposable obj)
{
obj.Dispose();
base.Remove(obj);
}
#region IDisposable Members
public void Dispose()
{
foreach (IDisposable d in this)
{
d.Dispose();
}
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
所以我的代码现在看起来像这样:
using (MultiDispose md = new MultiDispose())
{
StreamReader rdr = md.Add(new StreamReader(args[0]));
StreamWriter wrt = md.Add(new StreamWriter(args[1]));
WhateverElseNeedsDisposing w = md.Add(new WhateverElseNeedsDisposing());
// code
}
Run Code Online (Sandbox Code Playgroud)
这种方法有什么问题可以导致问题吗?我故意离开了从HashSet继承的Remove函数,以便该类更灵活.肯定滥用这个功能会导致物体没有被正确处理掉,但是在没有这个类的情况下还有很多其他方法可以在脚下射击.
Cha*_*ion 47
你可以这样做:
using (var a = new A())
using (var b = new B())
{
/// ...
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 20
关于一般原则的几点:
using
没有额外括号的情况下嵌套语句如果您有两个相同类型的变量,则可以使用单个using语句:
using (Stream input = File.OpenRead("input.dat"),
output = File.OpenWrite("output.dat"))
{
}
Run Code Online (Sandbox Code Playgroud)现在假设你真的想继续这样做:
Add
.HashSet<T>
或任何集合.你应该在类中有一个列表作为私有成员变量.Dispose
呼叫失败,则不会进行任何其他Dispose
呼叫; 使用传统using
语句,每次调用Dispose
都在自己的finally
块内进行.基本上,我认为这是一个坏主意.深度嵌套两层远非痛苦; 筑巢三应该是罕见的; 嵌套四个或更多强烈建议重构.你应该设计远离它,而不是试图应对深层筑巢的痛苦.
Chr*_*lor 13
也许只是你已经展示了一个简单的例子,但我认为以下内容更具可读性.
using (StreamReader rdr = new StreamReader(args[0]))
using (StreamWriter wrt = new StreamWriter(args[1]))
{
// code
}
Run Code Online (Sandbox Code Playgroud)
您可以using
通过仅使用一对大括号使嵌套语句更漂亮,如下所示:
using (StreamReader rdr = new StreamReader(args[0]))
using (StreamWriter wrt = new StreamWriter(args[1]))
{
///...
}
Run Code Online (Sandbox Code Playgroud)
要回答你的问题,你需要按照相反的顺序处理.
因此,你不能使用HashSet
.
此外,没有理由将IDisposable
s 列表暴露给外界.
因此,您不应该继承任何集合类,而是保持私有List<IDisposable>
.
然后你应该有公共Add<T>
和Dispose
方法(没有其他方法),并向后循环列表Dispose
.