Roslyn: Logical extension to else-if: also-if

Created on 21 Nov 2016  路  5Comments  路  Source: dotnet/roslyn

Consider the following use case:

if (Predicate1a && Predicate1b || Predicate1c)
{
    // Preliminary work.
    if ((Predicate2a || Predicate2b) && Predicate2c == false)
    {
        // Secondary work.
        if (Predicate3a && Predicate3b == false)
        {
            // In short, nested if recursion.
        }
    }
}

The suggested alternative is an inversion of "else if"; or "also if". Whereas "else if" executes only the first if conditional to return true and exits immediately after the context block, "also if" exits at the first expression to return false, and executes all previous if conditionals.

If an if-else-also sequence contains an "else if" followed by an "also if", the "also if" is considered part of the "else if" and executes, along with all immediately following "also if" statements. If an also-if is followed by an "else if", the "else if" is not considered part of the "also if", and no further if-else-also statements are considered.

The nested if is thus simplified to:

if (Predicate1a && Predicate1b || Predicate1c)
{
    // Preliminary work.
}
also if ((Predicate2a || Predicate2b) && Predicate2c == false)
{
    // Secondary work.
}
also if (Predicate3a && Predicate3b == false)
{
    // Tertiary work.
}

The resulting code functionality is exactly the same; if the tertiary code is called, then the two previous if statement context blocks were also executed, and more crucially, any variables declared in the previous contexts remain in scope.
However, the code itself is cleaner, easier to read, and takes up less screen real estate.

As a final note, I was surprised to find seemingly no discussion of this on a Google search. As such, I cannot claim any backing or support for this as a good idea; there may be obvious problems with it that I am missing. For example, "also" may be too close to "else" on a casual glance; in addition, the scope context rules are an exception to the "bracket assumptions". I also very much doubt I am the first person to have this idea. If I missed why this is a terrible idea, please note the reason, and then the mods can close it.

I apologize if I filed this in the wrong place. This is where I have seen other language enhancements suggested.

Area-Language Design

Most helpful comment

Or just invert conditions,

if (!(...)) return;
// Preliminary work.
if (!(...)) return;
// Secondary work.
if (!(...)) return;
// Blah

AFAIK there is a code fix that automatically does this for you.

All 5 comments

How will it work together with else? Will it be an else to the last also if in the chain?

"else if" and "also if" are separate statements. You wouldn't have "else also if". The behaviour of "also if" when followed by or following "else if" or "if" is described in the text, particularly the middle section.

Other than that, I'm not sure what you're asking, sorry.

What exactly is the problem? Is it the nesting of the blocks for each subsequent if statement?

Also, "else if" is two separate statements. It's else followed by an if as the embedded statement without an enclosing block. The fully expanded form would be:

if (condition1)
{
}
else
{
    if (condition2)
    {
    }
}

To fit also into the same syntactic structure it would need to be supported on its own:

if (condition)
{
    // primary work
}
also
{
    // secondary work
}

Let's take an example:
cs if (expression1) DoThing1(); also if (expression2) DoThing2(); else if (expression3) DoThing3(); also if (expression4) DoThing4();
I'm guessing that you'd want DoThing4() to be called if both expression3 and expression4 were true? It's not really obvious that that would be the case though and I could see it causing bugs.

Also, as @HaloFour has mentioned, else and if are two distinct statements, so the following are equivalent:

````cs
if (expression1)
DoThing1();
else if (expression2)
DoThing2();
else
DoThing3();

if (expression1)
{
DoThing1();
}
else
{
if (expression2)
{
DoThing2();
}
else
{
DoThing3();
}
}
````

So the new keyword would need to eg be alsoif as one word to avoid that also {} scenario that he mentions.

Finally, having lots of nested if's is a bit of a code smell and likely indicates code that needs a rethink and a rewrite into a simpler form. also if seems a bit too much like spraying air freshener to mask the smell instead.

Or just invert conditions,

if (!(...)) return;
// Preliminary work.
if (!(...)) return;
// Secondary work.
if (!(...)) return;
// Blah

AFAIK there is a code fix that automatically does this for you.

Was this page helpful?
0 / 5 - 0 ratings