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

时间:2008-10-21 11:20:55

标签: c# .net language-features

我希望在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 proposed以下

using(new Usable(delegate() {
    // actions here
}) {}

它可以在这样的示例场景中工作,但通常你已经分配了资源并希望它看起来像这样:

using (Repository.GlobalResource) 
{ 
  // actions here 
}

GlobalResource(是的,我知道全局资源不好)实现了IUsable。 你可以重写就像

一样短
Repository.GlobalResource.Use(() =>
{
  // actions here
});

但它看起来有点奇怪(如果你明确地实现接口会更奇怪),这种情况经常出现在各种风格中,我认为它应该是一种语言中新的语法糖。

3 个答案:

答案 0 :(得分:3)

恕我直言,我认为这种模式没有什么用处,因为:

  1. 使用块已经要求对象具有IDisposable接口,因此我们可以使用IDisposable接口进行受控执行
  2. 我们从哪里传递Action对象?
  3. 我已经使用IDisposable成功地将这种模式用于数据库操作。

答案 1 :(得分:2)

怎么样:

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。是的,它可能没有那么优雅,但至少大多数人习惯了它。

答案 2 :(得分:1)

您可以通过使用匿名委托来完成大部分操作:

using(new Usable(delegate() {
    // actions here
}) {}

当然,将它包装在某个函数中,或直接实现try / finally可能会使这不仅有用,而且甚至有点漂亮。