Line Saving Code Tricks – C#

Reducing lines of code can make your work more readable, making it easier for you and for others to read. More lines means more mental gymnastics to decipher which part of code does what. I want to go over some tips and tricks that helpd me.

This is a guide I’ll update periodically if I discover new line saving tricks. If you know one that I haven’t put in, post a comment below to let me know and it may end up in the guide!

Smart Booleans

A real line saving trick is being smart with booleans. Below is a typical scenario you might have with turning off an objects animator once a counter has finished counting down.

void Update()
{
    counter--;
    
    if(counter > 0)
    {
        animator.enabled = true;
    }
    else
    {
        animator.enabled = false;
    }
}

You can turn the eight lines of if / else statements into one line of code!

void Update()
{
    counter--;       
    animator.enabled = (counter > 0);    
}

The conditional check in the parentheses, ( counter > 0 ), returns a value of true or false. So if the counter is greater than 0, animator.enabled will be set to true. Otherwise it will be set to false. Try using it and saving lines in your projects!

Ternary Operator

There’s another way of getting rid of nested if statements and reducing line count. Consider again the example from above:

void Update()
{
    counter--;
    
    if(counter > 0)
    {
        animator.enabled = true;
    }
    else
    {
        animator.enabled = false;
    }
}

I showed you one way to reduce it to a single line. Here’s another:

void Update()
{
    counter--;       
    animator.enabled = (counter > 0) ? true : false;    
}

The structure is this:

variable = (condition) ? true value : false value;

Another example of using it is this:

void Update()
{
    counter--;       
    string result; 
    result = (counter > 0) ? "Still counting" : "Finished counting";    
}

You’re condensing an if / else condition and assigning the value to a single variable in one line, giving a different value depending on whether the condition is true or false. The usefulness in this case is it can be used to set anything, not just booleans. You can also declare and set the variable in one line:

string result = (counter > 0) ? "Still counting" : "Finished counting";

If you’re wondering which part is referred to as the ternary operator, aka conditional operator, it’s this ( ?: )

Smart Ternary Operators

You can be even cleverer with ternary operators. Take the following code:

public Light flashLight;
public AudioSource lightClick;
public AudioClip clickOn;
public AudioClip clickOff;

lightClick.clip = (flashLight.enabled) ? clickOff : clickOn; 
lightClick.Play();

You can set and play a sound with two lines of code the way we were using the ternary operator before, by using the ternary operator first to assign it to a variable, then to play it. But like with smart booleans, you can reduce the ternary operator to this:

(flashLight.enabled) ? clickOff : clickOn;

The above statement will return a different value for either true or false. What you may not have realised is you don’t have to assign it to a variable first. You can use it immediately:

lightClick.PlayOneShot((flashLight.enabled) ? clickOff : clickOn, 0.5f);

In one line we’ve set the audio clip and then played it. That is because AudioSource.PlayOneShot( ) takes an audio clip and a float as its arguments.

lightClick.PlayOneShot( audio clip, float);

By using the ternary operator as an argument, instead of first assigning it to a variable, we’ve saved more lines and learned something interesting about the way ternary operators work.

Passing Smart Arguments

Just to follow on from the subject of smart ternary operators and smart booleans, one way to save lines of code can be to pass declarative statements directly as arguments into functions. This is one situation where you will have to take it case by case. Sometimes it’s more readable, if there are lots of variables, to declare the variables first, because a very long line of code is hard to read. But in other cases, such as the above example, it will save lines of code and can even come up with creative programming solutions:

lightClick.PlayOneShot((flashLight.enabled) ? clickOff : clickOn, 0.5f);

Passing the ternary operator in as an argument is very easy to read in the above case. Be creative and consider in other situations if you can pass boolean statements directly into functions, ie:

SetSound( (flashLight.enabled) ? clickOff : clickOn);
SwitchLight( !flashLight.enabled );
CheckTimer( counter > 0 );

It’s not just booleans. You might want to create a new vector for a position, or some other kind of variable, and you can declare variables within the argument itself, such as:

MoveObject( new Vector3(0, 10, transform.position.x);
SetIntensity(Random.Range(0f, 1f));

Again, you don’t want to have your arguments so long that they aren’t readable, but this can be a time saver occasionally. There are also situations where this makes your code less re-usable and you may not want to do it, but it’s useful to know. Experiment and see what you can come up with.

Setting Multpile Variables In One Line

One useful trick is declaring and setting multiple variables in one line in C#. The traditional way:

int number1 = 0;
int number2 = 0;
int number3 = 0;

void Start()
{
    number 1 = 10;
    number 2 = 10;
    number 3 = 10;
}

It can be re-written like this:

int number1, number2, number3 = 0;

void Start()
{
    number 1 = number2 = number3 = 10;
}

Useful especially if you are regularly storing variables to keep track of various data and constantly changing multiple variables at once.

Enums to Replace Multiple Variables

Just to counter the previous suggestion, if you find you are regularly changing lots of variables, especially booleans, consider an enum. An example would be a player character in a platformer. They might be standing, jumping, or falling, but they can never be all three at once. Since the states are mutually exclusive and can’t happen at the same time, instead of having 3 separate boolean checks, you can use an enum. You could write the following:

Enum PlayerState
{
      Grounded = 0,
      Jumping = 1,
      Falling = 2
}
PlayerState playerState = PlayerState.Grounded;

void TryJump()
{
     if ( playerState == PlayerState.Grounded)
          Jump();
}

void Jump()
{
     playerState = PlayerState.Jumping;
     player.rigidBody.AddForce( jumpForce * jumpSpeed );
}

void OnCollisionEnter(Collider other)
{
    if( other.gameObject.tag == "Ground")
    {
        playerState = PlayerState.Grounded;
        player.rigidBody.velocity = Velocity.Zero;
    }       
}

How much nicer is that than turning each invidual boolean on and off for the player’s states?

The Not Operator

The not operator is used to change the state of something to it’s opposite value; if it is true, it will make it false. Example with turning on a flashlight:

void Update ()    
{        
    if (Input.GetMouseButtonDown(0)) 
    {           
        flashLight.enabled = !flashLight.enabled; 
    }
}

What the above statement does is, if the flash light is enabled, it turns turns it off. If it’s off, it turns it back on, all in one statement. It could be written as:

flashLight.enabled   =   the opposite state of flashLight.enabled;

It’s much shorter than manually checking for both the enabled and disabled states of the flash light separately, and then manually changing it to the opposite state. There are of course other uses with the operator, such as:

if (value != true)  
{          
   value = true; 
}

which works in a similar way, because you are checking if something is not true, instead of:

if (value == false)

Dropping Curly Braces

Curly braces are fantastic to see where a statement begins and ends. However, there are many cases where braces aren’t needed if you have single line loops or single line if / else statements. I don’t recommend dropping braces for functions. You can drop the curly braces if:

  • Your loop runs one line of code
  • Your conditional statement has one line of code

However, if you have an if statement that runs two lines of code, the program will think your second line does not belong to the if statement, so be careful!

An example of dropping curly braces correctly:

foreach ( CornKernel kernal in myPopcorn )
     StartEating();

if ( allCornEaten )
    GetNewBowl();
else 
    ContinueEating();

See how clean and easy to read that is? When you consider that every pair of curly braces adds 2 more lines to your code, a single line loop can become 2 lines instead of 4. You can end up saving a lot of lines and make things much more readable!

There are additional cases for dropping curly braces, but be careful of not getting too carried away.  If you are nesting too many loops and if statements, there’s possibly a better way of doing things. This also works:

void Start()
{  
    List<int> numberList = new List<int>() { 1, 2, 3, 4, 5 };

    if (10 > 0)
        for (int i = 0; i < numberList.Count; i++)
            if (numberList[i] > 0)
                Debug.Log(numberList[i]);
}

 

The reason the above code works is because when you drop the curly brace, the program checks the next line, so you can nest if statements and loops like this. Once you’ve stepped down a level, however, you can never step back up if you left off the braces. You can’t do this:

void Update()
{  
    List<int> numberList = new List<int>() { 1, 2, 3, 4, 5 };
    numberChanger++;

    if ( numberChanger > 5)
        for (int i = 0; i < numberList.Count; i++)            
                Debug.Log(numberList[i]);
    else
        for (int i = 0; i < numberList.Count; i++)            
                Debug.Log(numberList[i]);                
}

If you tried to run that code, you would find the else statement never runs. This is because while you can drop down a level of nesting if statements or for loops below each other, you can never return back up to a level you have stepped down from. You also can’t do the following:

void Start()
{  
    List<int> numberList = new List<int>() { 1, 2, 3, 4, 5 };
    int numberChanger = 0;

    if (10 > 0)
        for (int i = 0; i < numberList.Count; i++)
            if (numberList[i] > 0)
                Debug.Log(numberList[i]);
                numberChanger += 1;
}

If you tried to run the above code, you would find the variable number changer is always set to 1 because it is below the first line after the conditional statement. It’s considered as separate from the if statement. You can, however, do this:

void Start()
{  
    List<int> numberList = new List<int>() { 1, 2, 3, 4, 5 };
    int numberChanger = 0;

    if (10 > 0)
        for (int i = 0; i < numberList.Count; i++)
            if (numberList[i] > 0)
            {
                Debug.Log(numberList[i]);
                Debug.Log("I am working!");
            }                
}

The reason that works is because on the final if statement, we used curly braces. You still can’t step back up levels and run an else condition after if (10 > 0). You also can’t do anything after the last if statement because of the way that code steps down a level, so you can’t run any extra else statements.

Programming this way can seem a little confusing at first. The best way to figure it out is to try some experiments yourself printing sets of numbers and manipulating variables and try different condition checks. See what works. If you are confused, don’t try nesting multiple loops and if statements without the curly braces until you are more confident, but it really does make code more readable. Start with dropping curly braces for single line loops and if statements, and then experiment from there as your confidence grows.

Don’t Copy Paste

If you are copy pasting the same code into more than one location, it should be a function so you can re-use the code. Re-using code in functions has many benefits.

  • It’s easier to find errors
  • If you make changes, you only have to change it in one place
  • It reduces lines of code
  • It makes your code easier to understand

For example, say you were working on UI for an inventory system, and every time you sold or dropped an item, you wanted the inventory to re-sort itself. Having a single function you call everywhere you want your inventory sorted makes your code simpler to understand by reducing lines of code and makes it easier to change and debug problems.

Conclusion

 

Remember, above all else, make sure your code stays readable! Don’t get carried away being smart saving lines but making it harder to understand your code. The goal at the end of the day is to try and make your code easier for you and everyone else to understand, so keep that as the golden rule. My next article will be on good principles for writing readable code and will follow on from this.

 

 

 

Advertisements

2 thoughts on “Line Saving Code Tricks – C#

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s