cki*_*tel 9 c# refactoring using-statement code-duplication
我有一些代码有很多重复.问题来自我正在处理嵌套IDisposable类型的事实.今天我有一些看起来像:
public void UpdateFromXml(Guid innerId, XDocument someXml)
{
using (var a = SomeFactory.GetA(_uri))
using (var b = a.GetB(_id))
using (var c = b.GetC(innerId))
{
var cWrapper = new SomeWrapper(c);
cWrapper.Update(someXml);
}
}
public bool GetSomeValueById(Guid innerId)
{
using (var a = SomeFactory.GetA(_uri))
using (var b = a.GetB(_id))
using (var c = b.GetC(innerId))
{
return c.GetSomeValue();
}
}
Run Code Online (Sandbox Code Playgroud)
using对于这些方法中的每一个,整个嵌套块都是相同的(显示了两个,但是大约有十个).唯一不同的是当你到达using块的内层时会发生什么.
我想的一种方法是做一些事情:
public void UpdateFromXml(Guid innerId, XDocument someXml)
{
ActOnC(innerId, c =>
{
var cWrapper = new SomeWrapper(c);
cWrapper.Update(someXml);
});
}
public bool GetSomeValueById(Guid innerId)
{
var result = null;
ActOnC(innerId, c => { result = c.GetSomeValue(); });
return result;
}
private void ActOnC(Guid innerId, Action<TheCType> action)
{
using (var a = SomeFactory.GetA(_uri))
using (var b = a.GetB(_id))
using (var c = b.GetC(innerId))
{
action(c);
}
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,它只是一种笨重的解析(作为一个人). 有没有人对如何减少using像这样的嵌套块的代码重复有任何其他建议? 如果他们不是IDisposable那么人们可能只是创建一个方法来返回...的结果,b.GetC(innerId)但这不是这里的情况.
我喜欢BFree提供的答案作为开始,但我会做一些修改。
//Give it a better name; this isn't designed to be a general purpose class
public class MyCompositeDisposable : IDisposable
{
public MyCompositeDisposable (string uri, int id, int innerid)
{
A = SomeFactory.GetA(uri);
B = A.GetB(id);
C = B.GetC(innerId);
}
//You can make A & B private if appropriate;
//not sure if all three or just C should be exposed publicly.
//Class names are made up; you'll need to fix.
//They should also probably be given more meaningful names.
public ClassA A{get;private set;}
public ClassB B{get;private set;}
public ClassC C{get;private set;}
public void Dispose()
{
A.Dispose();
B.Dispose();
C.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
完成此操作后,您可以执行以下操作:
public bool GetSomeValueById(Guid innerId)
{
using(MyCompositeDisposable d = new MyCompositeDisposable(_uri, _id, innerId))
{
return d.C.GetSomeValue();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,MyCompositeDisposable 可能需要在构造函数和 Dispose 方法中具有 try/finally 块,以便创建/销毁中的错误正确确保没有任何内容最终未处理。