1

我希望我们在 C# 中有“可用”模式,当 using 构造的代码块将作为委托传递给函数时:

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
}

优点:

  • 受控执行,异常
  • 使用“可用”的事实在调用堆栈中可见

缺点:

  • 委托费用

你认为它是否可行和有用,如果从语言的角度来看它没有任何问题?有没有你能看到的陷阱?

编辑:大卫施密特提出以下

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

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

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

GlobalResource(是的,我知道全球资源不好)实现 IUsable 的地方。你可以重写的时间很短

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

但它看起来有点奇怪(如果你显式地实现接口,那就更奇怪了),而且这种情况在各种风格中都很常见,我认为它应该成为一种语言中的新语法糖。

4

3 回答 3

3

恕我直言,我看不出这种模式有什么用处,因为:

  1. using 块已经要求对象具有 IDisposable 接口,因此我们可以使用 IDisposable 接口进行受控执行
  2. 我们从哪里传递 Action 对象?

我已经使用 IDisposable 成功地将这种模式用于数据库操作。

于 2008-10-21T11:37:05.153 回答
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。是的,它可能没有它应该的那么优雅,但至少大多数人已经习惯了。

于 2008-10-21T13:41:54.857 回答
1

通过使用这样的匿名委托,您已经可以拥有大部分内容:

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

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

于 2008-10-21T11:32:08.270 回答