I do think the approach is over complicated, but in some cases there may be (a small) benefit. As an alternative I would offer:
First version (no common test):
((Action)(() =>
{
if (!Step1())
return;
if (!Step2())
return;
}))();
Second version (common test):
((Action)(() =>
{
Func<int, bool> Test = (itemToTest) =>
{
return itemToTest > 0;
};
if (!Test(Step1()))
return;
if (!Test(Step2()))
return;
}))();
After giving it some more thought, I come to the conclusion that there is (in my opinion) a still more readable way of doing things. The problem (I think) is that it needs the function pointer array (and I do not like that).
foreach (Func<int> Step in new Func<int>[] { Step0, Step1, Step2, Step3 })
if (Step() > 1)
break;
After giving it even more thought, I come to the conclusion that there is (in my opinion) a still more readable way of doing things. The problem (I think) is that it also needs the function pointer array (and I still do not like that). And this one can be implemented using a extension method (this may be the way to do it if you use this kind of code more often).
static class Extensions
{
public static void InvokeUntilFalse<T>(
this IEnumerable<Func<T>> Steps, Func<T, bool> Test)
{
foreach (Func<T> Step in Steps)
if (!Test(Step()))
break;
}
}
(new Func<int>[] { Step0, Step1, Step2, Step3 })
.InvokeUntilFalse<int>((ToTest) => { return ToTest < 2; });
And this is almost like the one that was proposed by the OP. Mmmm time for my vote of 5 :)
new Func<bool>[]
{
Step1,
() => Step2(1, 1),
Step3,
Step4,
() => 0 == 1
}.Any((step) => !step());