Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

Call Functions Until One Meets Condition

0.00/5 (No votes)
24 Jun 2011CPOL 6.7K  
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...
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):
C#
((Action)(() =>
{
    if (!Step1())
        return;
    if (!Step2())
        return;
}))();


Second version (common test):
C#
((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).
C#
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).
C#
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 :)
C#
new Func<bool>[]
{
    Step1,
    // You can use a lambda to wrap a function with a different signature.
    () => Step2(1, 1),
    Step3,
    Step4,
    // You can use a lambda to avoid the use of a function.
    () => 0 == 1
}.Any((step) => !step());

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)