views:

167

answers:

3

I wish we have "Usable" pattern in C#, when code block of using construct would be passed to a function as delegate:

class Usable : IUsable
{
  public void Use(Action action)  // implements IUsable
  {
    // acquire resources
     action();
    // release resources
  }
}

and in user code:

using (new Usable())
{
  // this code block is converted to delegate and passed to Use method above
}

Pros:

  • Controlled execution, exceptions
  • The fact of using "Usable" is visible in call stack

Cons:

  • Cost of delegate

Do you think it is feasible and useful, and if it doesn't have any problems from the language point of view? Are there any pitfalls you can see?

EDIT: David Schmitt proposed the following

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

It can work in the sample scenario like that, but usually you have resource already allocated and want it to look like this:

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

Where GlobalResource (yes, I know global resources are bad) implements IUsable. You can rewrite is as short as

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

But it looks a little bit weird (and more weird if you implement interface explicitly), and this is so often case in various flavours, that I thought it deserve to be new syntactic sugar in a language.

+1  A: 

You can already have most of this by using an anonymous delegate like this:

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

Of course, wrapping that away in some function, or directly implementing the try/finally might make this not only useful, but even a bit pretty.

David Schmitt
+3  A: 

IMHO, I don't see any great use for this pattern because:

  1. using block already requires the object to have IDisposable interface, so we can use the IDisposable interface for controlled execution
  2. From where do we pass the Action object here?

I had already used this kind of pattern successfully for database actions using IDisposable.

nullDev
+2  A: 

What about:

class Usable<T> where T : ICriticalResource, new()
{
    static void Do(Action<T> action) {
        ICriticalResource resource = new T();
        resource.Acquire();
        action(resource);
        resource.Relese();
    }
}

Then you use it for everything that implements ICritialResource.

Usable<SomeResource>.Do(resource => resource.SomeMethod());

Another option is to use IDisposable just the way it is. Yes, it might not be as elegant as it could be, but at least most people are used to it.

Hallgrim