Reputation: 12142
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:
Cons:
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.
Upvotes: 1
Views: 365
Reputation: 15513
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.
Upvotes: 2
Reputation: 11607
IMHO, I don't see any great use for this pattern because:
I had already used this kind of pattern successfully for database actions using IDisposable.
Upvotes: 3
Reputation: 59355
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.
Upvotes: 1