1
\$\begingroup\$

I'm writing a project, and the part I'm doing now is getting bloated real fast. How can I remove this nested if statements, but still have the same behaviour?

It would be nice the the resulting code was succinct, and extra local flags weren't required. This might not look so bad now, but I'm planning on writing more methods, up to T16, you can imagine how bad these nested if statements will get.

using ContainerExpressions.Containers;
using System;

namespace ContainerExpressions.Expressions.Core
{
    internal static class Compose
    {
        public static Response<T> Evaluate<T>(Func<Response<T>> func) => func();

        public static Response<TResult> Evaluate<T1, TResult>(Func<Response<T1>> func1, Func<T1, Response<TResult>> funcResult)
        {
            var response = new Response<TResult>();

            var result = func1();
            if (result)
            {
                response = response.WithValue(funcResult(result));
            }

            return response;
        }

        public static Response<TResult> Evaluate<T1, T2, TResult>(Func<Response<T1>> func1, Func<T1, Response<T2>> func2, Func<T2, Response<TResult>> funcResult)
        {
            var response = new Response<TResult>();

            var result1 = func1();
            if (result1)
            {
                var result2 = func2(result1);
                if (result2)
                {
                    response = response.WithValue(funcResult(result2));
                }
            }

            return response;
        }

        public static Response<TResult> Evaluate<T1, T2, T3, TResult>(Func<Response<T1>> func1, Func<T1, Response<T2>> func2, Func<T2, Response<T3>> func3, Func<T3, Response<TResult>> funcResult)
        {
            var response = new Response<TResult>();

            var result1 = func1();
            if (result1)
            {
                var result2 = func2(result1);
                if (result2)
                {
                    var result3 = func3(result2);
                    if (result3)
                    {
                        response = response.WithValue(funcResult(result3));
                    }
                }
            }

            return response;
        }
    }
}
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

If your code will always behave as the parts shown, you can refactor it to early-out returns. I show your Evaluate<T1, T2, T3, TResult>(...) as an example:

public static Response<TResult> Evaluate<T1, T2, T3, TResult>(Func<Response<T1>> func1, Func<T1, Response<T2>> func2, Func<T2, Response<T3>> func3, Func<T3, Response<TResult>> funcResult)
{
    var response = new Response<TResult>();

    if (!func1()) return response;
    if (!func2(true)) return response;
    if (!func3(true)) return response;
    return response.WithValue(funcResult(result3));
}

So you get rid of the nesting if statements. And you don't need the local flag variables since you know that the value is true.

\$\endgroup\$
1
  • \$\begingroup\$ I gave simon the other one, so you can have this one, thanks mate. \$\endgroup\$ Commented Mar 23, 2016 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.