删除嵌套的if语句

时间:2016-03-23 12:21:59

标签: c#

您好我正在写project,而我现在所做的部分正在迅速变得臃肿。如何删除此嵌套的if语句,但仍具有相同的行为?

结果代码简洁明了,并不需要额外的本地标志。下面的代码现在可能看起来不那么糟糕,但是我计划编写更多方法,直到 T16 ,你可以想象这些嵌套的if语句会有多糟糕。

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;
        }
    }
}

我最终创建的代码

在我复活的建议后,我的代码膨胀了,现在看起来如下:

using ContainerExpressions.Containers;
using System;
using System.Runtime.CompilerServices;

namespace ContainerExpressions.Expressions.Core
{
    internal static class Compose
    {
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static Response<TResult> Evaluate<T1, TResult>(Func<Response<T1>> func1, Func<T1, Response<TResult>> funcResult)
        {
            var result = func1();
            return result ? funcResult(result) : Response.Create<TResult>();
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static Response<TResult> Evaluate<T1, T2, TResult>(Func<Response<T1>> func1, Func<T1, Response<T2>> func2, Func<T2, Response<TResult>> funcResult)
        {
            var result = func1();
            return result ? Evaluate(() => func2(result), funcResult) : Response.Create<TResult>();
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        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 result = func1();
            return result ? Evaluate(() => func2(result), func3, funcResult) : Response.Create<TResult>();
        }
    }
}

2 个答案:

答案 0 :(得分:2)

如何重复使用其他方法,如下所示:

internal static class Compose
{
    public static Response<T> Evaluate<T>(Func<Response<T>> func) => func();

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    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;
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static Response<TResult> Evaluate<T1, T2, TResult>(Func<Response<T1>> func1, Func<T1, Response<T2>> func2, Func<T2, Response<TResult>> funcResult)
    {
        return func1() ? Evaluate(func2, funcResult) : new Response<TResult>();
    }

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    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)
    {
        return func1() ? Evaluate(func2, func3, funcResult) : new Response<TResult>();
    }
}

答案 1 :(得分:0)

如果您的代码始终表现为所显示的部分,则可以将其重构为 early-out 返回。我以Evaluate<T1, T2, T3, TResult>(...)为例展示:

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(true));
}

所以你摆脱了嵌套if语句。并且您不需要本地标志变量,因为您知道该值为true

结合Simon Karlsson的回答,您的代码可能如下所示:

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>();
    return func1() ? response.WithValue(funcResult(result)) : 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>();
    return func1() ? Evaluate(func2, funcResult) ? : 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>();
    return func1() ? Evaluate(func2, func3, funcResult) : response;
}