1

構成を使用するコードブロックがデリゲートとして関数に渡される場合、C#に「Usable」パターンがあればいいのにと思います。

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
}

長所:

  • 制御された実行、例外
  • 「Usable」を使用した事実は、コールスタックに表示されます

短所:

  • 代理人の費用

それは実現可能で有用だと思いますか、そして言語の観点から問題がなければ?あなたが見ることができる落とし穴はありますか?

編集:デビッドシュミットは次のことを提案しました

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

このようなサンプルシナリオでは機能しますが、通常はリソースがすでに割り当てられており、次のように表示する必要があります。

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

GlobalResource(はい、グローバルリソースが悪いことは知っています)がIUsableを実装している場合。あなたが書き直すことができるのは短いです

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

しかし、それは少し奇妙に見えます(そして、インターフェースを明示的に実装するとさらに奇妙になります)。これはさまざまなフレーバーで非常によくあることなので、言語の新しい構文糖衣に値すると思いました。

4

3 に答える 3

3

私見、私はこのパターンの素晴らしい使用法を見ていません。理由は次のとおりです。

  1. ブロックを使用するには、オブジェクトに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());

もう 1 つのオプションは、IDisposable をそのまま使用することです。はい、可能な限りエレガントではないかもしれませんが、少なくともほとんどの人はそれに慣れています.

于 2008-10-21T13:41:54.857 に答える
1

次のような匿名の代理人を使用することで、すでにこのほとんどを利用できます。

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

もちろん、それをいくつかの関数でラップしたり、try / finalを直接実装したりすると、これが便利になるだけでなく、少しでもきれいになる可能性があります。

于 2008-10-21T11:32:08.270 に答える