您好我正在写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>();
}
}
}
答案 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;
}