We have the following construct in our code base, used to ensure that a specific resource is deleted after use:
using (var disposableThing = DisposableThing.Begin())
{
disposableThing.Finish();
}
Here is an example of its use:
List<int> ids;
using (var disposableThing = DisposableThing.Begin())
{
ids = disposableThing.GetSomeIds();
disposableThing.Finish();
}
DoSomethingElseWith(ids);
Since this pattern is so common, we wrote a method DisposableThingto encapsulate it:
static void ExecuteWithFinish(Action<DisposableThing> action)
{
using (var disposableThing = Begin())
{
action(disposableThing);
disposableThing.Finish();
}
}
which allows us to rewrite the second sample as:
List<int> ids;
DisposableThing.ExecuteWithFinish(disposableThing =>
{
ids = disposableThing.GetSomeIds();
});
DoSomethingElseWith(ids);
But the compiler refuses to compile this code because it does not know what idswill always be assigned after completion ExecuteWithFinish(or throws an exception, which in any case will prevent execution DoSomethingElseWith).
- I know that I can add an overload
ExecuteWithFinishthat returns values ββfrom the passed Func, which is ugly. - ,
DisposableThing Dispose Finish, , , (, , ).
", ", , # 4 ?
: , , List<int> ids = null; , () (b) .