Search code examples
c#datetimeif-statementternary

How do I convert nested ternary operator to nested if-else statements?


I'm having a hard time trying to convert the following C# code into a if-else statement, so that I can understand the business logic. Can anybody help me, checking whether my conversion is ok?

Code:

dateInit = objInstance == null ? (DateTime?)null:
                objInstance.DateAnt == null ?
                    objInstance.DatePost > otherObjInstance.DateCon ?
                        (DateTime?)null :
                        objInstance.DatePost :
                objInstance.DateAnt;

My conversion:

if (objInstance == null)
{
    dateInit = (DateTime?)null;
}
else
{
    if (objInstance.DateAnt == null)
    {
        if (objInstance.DatePost > otherObjInstance.DateCon)
        {
            dateInit = (DateTime?)null;
        }
        else
        {
            dateInit = objInstance.DatePost;
        }
    }
    else
    {
        dateInit = objInstance.DataAnt;
    }
}

Solution

  • Your conversion appears to be correct. However, I would improve it in two ways.

    First, the casts on null are unnecessary in the if form. (The ?: operator has certain restrictions on the types that can appear in the consequence and alternative positions, which leads to developers inserting casts.)

    Second, the if statements are unnecessarily nested. The whole thing could be expressed much more readably as:

    if (objInstance == null)
      dateInit = null;
    else if (objInstance.DateAnt != null)
      dateInit = objInstance.DataAnt;
    else if (objInstance.DatePost > otherObjInstance.DateCon)
      dateInit = null;
    else
      dateInit = objInstance.DatePost;
    

    The business logic is more understandable from this version than your version I think.

    We can make this transformation using two rules. First:

    if (x)
      X
    else 
    {
      if (y)
        Y
      else
        Z
    }
    

    is the same as

    if (x)
      X
    else if (y)
      Y
    else
      Z
    

    Which is simpler on the page.

    And second:

    if (x)
    {
      if (y)
        Y
      else
        Z
    }
    else
      NX
    

    is the same as

    if (!x)
      NX
    else 
    {
      if (y)
        Y
      else
        Z
    }
    

    And now we're in the first case again and can simplify further.

    By repeatedly combining these rules you can simplify a lot of complicated if-else statements.