IUisable:以比IDisposable更好的方式控制资源
本文关键字:方式 控制 资源 更好 以比 IDisposable IUisable | 更新日期: 2023-09-27 17:48:48
我希望我们在C#中有"可用"模式,当使用构造的代码块将作为委托传递给函数时:
class Usable : IUsable
{
public void Use(Action action) // implements IUsable
{
// acquire resources
action();
// release resources
}
}
和在用户代码中:
using (new Usable())
{
// this code block is converted to delegate and passed to Use method above
}
优点:
- 受控执行,例外
- 在调用堆栈中可以看到使用"可用"的事实
缺点:
- 委托费用
你认为这是可行和有用的吗?如果从语言的角度来看没有任何问题的话?你能看到什么陷阱吗?
编辑:David Schmitt提出了以下
using(new Usable(delegate() {
// actions here
}) {}
它可以在这样的示例场景中工作,但通常您已经分配了资源,并希望它看起来像这样:
using (Repository.GlobalResource)
{
// actions here
}
GlobalResource(是的,我知道全局资源不好)实现IUisable的地方。你可以重写短如
Repository.GlobalResource.Use(() =>
{
// actions here
});
但它看起来有点奇怪(如果显式实现接口,会更奇怪),而且这种情况在各种风格中都很常见,我认为它应该成为语言中的新语法糖。
IMHO,我认为这种模式没有什么大的用处,因为:
- 使用块已经要求对象具有IDisposable接口,因此我们可以使用IDisposaable接口进行受控执行
- 我们从哪里传递Action对象
我已经使用IDisposable成功地将这种模式用于数据库操作。
关于:
class Usable<T> where T : ICriticalResource, new()
{
static void Do(Action<T> action) {
ICriticalResource resource = new T();
resource.Acquire();
action(resource);
resource.Relese();
}
}
然后将它用于实现ICritialResource的所有内容。
Usable<SomeResource>.Do(resource => resource.SomeMethod());
另一种选择是按原样使用IDisposable。是的,它可能没有那么优雅,但至少大多数人已经习惯了。
通过使用这样的匿名委托,您已经可以拥有大部分内容:
using(new Usable(delegate() {
// actions here
}) {}
当然,将其封装在某个函数中,或者直接实现try/finaly,可能不仅有用,甚至有点漂亮。