重构if块

时间:2018-07-27 12:24:29

标签: c# if-statement conditional refactoring

在下面的代码中,我有2个if块。
A,当对象为null时,第一个返回错误。
B,第二个将尝试发送对象,如果失败,则返回并返回错误。仅当不是A且对象不为null时,才应执行该操作。

private bool SendToERP(Foo foo, out string error)
{
    error = "";
    var ticketIn = TicketFromFoo(foo, out string err);

    if(ticketIn == null)
    {
        error = err;
        return false;
    }

    if ( !GenericERP_TicketSubmit(ticketIn, out err))
    {
        error = err;
        return false;
    }

    return true;
}

这些条件之后的动作相同,我想将其重构为唯一的if块。

由于我无法改变头2的状况,所以我写了simple truth table来帮助我,and也是如此。但这并没有帮助我。

3 个答案:

答案 0 :(得分:8)

&&||运算符发生短路。从左到右考虑。这意味着:

1)如果&&将其第一个操作数评估为false,则不会评估其第二个操作数。

2)如果||将其第一个操作数评估为true,则不评估其第二个操作数。

在您的情况下,如果ticketIn为空,则您不希望执行TicketSubmit。 因此,您可以通过OR将2个条件分组。这样。

    var ticketIn = TicketFromFoo(foo, out string err);        
    if(ticketIn == null || !GenericERP_TicketSubmit(ticketIn, out err))
    {
         error = err;
         return false;
    }
    return true;

答案 1 :(得分:4)

在您的问题中,您可以将两个IF组合为@Thierry V答案

if(ticketIn == null || !GenericERP_TicketSubmit(ticketIn, out err))

但是我们可以用另一个角度来阅读问题。该函数期望返回bool,因此我们只能写一条语句而不是IF

return !(ticketIn == null || !GenericERP_TicketSubmit(ticketIn, out err))

我们可以使用另一项技能(De Morgan's laws)让!进入语句,即 将颠倒所有逻辑,使代码更清晰。

1。ticketIn == null将是ticketIn != null

2。||将是&&

3。!GenericERP_TicketSubmit(ticketIn, out err)将是GenericERP_TicketSubmit(ticketIn, out err)

这样我们就可以得到

return ticketIn != null && GenericERP_TicketSubmit(ticketIn, out err)

代码可以使用like。

private bool SendToERP(Foo foo, out string error)
{
    error = "";

    var ticketIn = TicketFromFoo(foo, out error);

    return ticketIn != null && GenericERP_TicketSubmit(ticketIn, out error);
}

答案 2 :(得分:1)

我建议使用新的Value Tuples查找c#7。我们还可以通过这种方式重构所有代码:

    private (bool result, string error) SendToERP(Foo foo)
    {
        var result = TryMakeTicketFromFoo(foo, out TicketIn ticketIn);
        return result.isSuccess ? GenericERP_TicketSubmit(ticketIn) : result;
    }

您还需要重构其他方法的语义:

    private (bool isSuccess, string error) GenericERP_TicketSubmit(TicketIn ticketIn)
    {
        throw new NotImplementedException();
    }

    private (bool isSuccess, string error) TryMakeTicketFromFoo(Foo foo, out TicketIn ticketIn)
    {
        throw new NotImplementedException();
    }