Some love for the ternary operator, and C# features I am missing

I have been programming with the C# language for about three months by now. This blog shall be a review on some things that have made me think about the language as such.

Multi-line ternary operators

One of the features of C# that I am a very big fan of is the ternary operator. The ternary operator is mainly a shorthand for an if / else construction, where in either block only a variable is assigned a value, so instead of this:

int b;
if (a > 5)
{
    b = 10;
}
else
{
    b = 0;
}

one can simply write:

int b = (a > 5) ? 10 : 0

The brackets are optional, but sometimes help to distinguish which part of the statement is the condition and which is the assignment.

 

There's not much to debate on whether in this case the use of the ternary operator is appropriate or not. However, I have been using it quite often in a different situation, and there was quite some disagreement between my supervisors, that have been using C# for many years already, and me about it. That situation is to use the ternary operator as a shorthand resp. compact way to write a switch statement which has only one variable assignment in each block.

 

An example of this is the following one, which I am using in an exercise program I am currently developing (a remake of the retro game "Invaders"):

InvaderType invaderType =
    row == 0 ? InvaderType.Spaceship :
    row == 1 ? InvaderType.Bug :
    row == 2 ? InvaderType.Saucer :
    row == 3 ? InvaderType.Satellite :
    /* else */ InvaderType.Star;

This would be a shorthand for this:

InvaderType invaderType;
switch (row)
{
    case 0:
        invaderType = InvaderType.Spaceship;
        break;
    case 1:
        invaderType = InvaderType.Bug;
        break;
    case 2:
        invaderType = InvaderType.Saucer;
        break;
    case 3:
        invaderType = InvaderType.Satellite;
        break;
    default:
        invaderType = InvaderType.Star;
        break;
}

Now, yes it is a lot of action for something that's technically a one-liner, but if the stacked ternary operator is displayed on multiple lines like this I think it's a lot easier to read than the switch statement, which has a lot of empty space between the really interesting bits of information.

 

I tried to investigate a little on whether there's any arguments performance-wise for either of the solutions, however the observations other people have published are varying very widely. The result that was found most often though was that the switch statement is faster than the if -- else if -- else construction and that the if -- else construction is about as fast as the ternary operator. But as said, other people with other ways of investigating on the performance of these structures got wholly different results, so after all I cannot really tell what is the case and what is not.

 

For that reason I will continue using this kind of structure, unless I really happen to come along a good reason not to do so.

Missing C#-Features

I really adore the many little things that are available to make C#-code look nice. Having programmed Java before I was especially delighted by the many small features that offer more flexibility to write certain structures in different ways.

 

Still there were multiple situations where I tried writing some code which C# just would not want to compile, but which would have been very handy in that certain situation. Thus I want to quickly present these features that I wished, C# would have.

Ternary operator statements

I really do like the ternary operator a lot, thats why most ideas revolve around it. The ternary operator can only be used as an expression, which means it returns a value which then has to be used as part of another statement, i.e. a method call or a variable assignment. However it'd be nice, if a ternary operator could be used to build a conditional statement, for example like this:

gameState == GameState.GameOver ? return : NextRound();

Which would be a short way to write this:

if (gameState == GameState.GameOver)
{
    return;
}
else
{
    NextRound();
}

respectively the already valid shorthand:

if (gameState == GameState.GameOver) return;
else NextRound();

Implicit ternary operation return value inheritance handling

So, earlier I tried to solve the assignment of the Invader types (as seen above) a bit differently: Instead of using an enum listing all the invader types I created a class for each type, each of them inheriting from the Invader class. Then I tried the following statement:

Invader newInvader =
    row == 0 ? new Spaceship() :
    row == 1 ? new Bug() :
    row == 2 ? new Saucer() :
    row == 3 ? new Satellite() :
    /* else */ new Star();

However this won't compile, even though each assignment (i.e. Invader newInvader = new Spaceship();) would be completely valid. The problem is, that the ternary operator needs to figure out its return type, and as it can not implictly upcast the types it returns, it can not determine of which type it is. This working would be a nice addition to C#!

Static abstract properties

This last idea has nothing to do with the ternary operator for once. The idea came to me for the following problem: In the Invaders game there is the ship of the player (class "Player") and the ships of the enemies (class "Invader"). As both are spaceships, they both inherit from the abstract class "Ship". Each ship has a certain size. The size of the player's ship is a different one than the Invaders' ships size, but all instances of the Invader (and Player) class have the same size. For that reason it would be sensible to make the "Size" property static, as it's the same for all instances of a certain type (subclass) of ship, especially as it may want to be used prior to creating any instances, for example to determine where on the play area to spawn the ships. On the same time it would be sensible to make it abstract, forcing either subclass to define a size, as both require a size to be placed and interacted with on the play area. However, unfortunately, the following line in the abstract Ship class won't compile:

public static abstract Size Size { get; set; }