IUisable:以比IDisposable更好的方式控制资源



我希望我们在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,我认为这种模式没有什么大的用处,因为:

  1. 使用块已经要求对象具有IDisposable接口,因此我们可以使用IDisposaable接口进行受控执行
  2. 我们从哪里传递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,可能不仅有用,甚至有点漂亮。

最新更新