Line Saving Code Tips – C#

Reducing lines of code can make your work more readable, making it easier for you and others to read. More lines means more mental gymnastics to decipher which part of code does what. I want to go over some techniques that helped make my life a lot easier while making Puzzledorf, my recent game release.

I’ll update this guide if I discover new tips. If you know a new one, post a comment below.

Smart Booleans

A real line saver 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.

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();

The above code chooses one of two audio clips and then plays the sound. But you can write ternary operators as follows:

(flashLight.enabled) ? clickOff : clickOn;

The above simply returns one of two different audio clips. This allows us to set and play our sound in one line:

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

AudioSource.PlayOneShot( ) takes an audio clip and a float as its arguments.

lightClick.PlayOneShot( AudioClip, float);

Passing Smart Arguments

A very long line of code can be hard to read so adding extra lines to declare variables before using a function is sometimes more readable. But doing something like the following is quicker and can sometimes be easier to read:

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

I say can be easier to read because, the more lines of code you have to read, the easier it is to misread and make mistakes as lines blur together. The above case is easy to read if you’re used to ternary operators (it’s worth getting used to them).

Passing booleans directly into functions is even easier to read:

SwitchLight( !flashLight.enabled ); // turns the flashlight on or off
CheckTimer( counter > 0 ); // is the timer greater than 0?

It’s not just booleans.You can declare lots of variable types within the argument itself:

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

You don’t your arguments too long, but this can be a time saver.  There are situations where this makes your code less re-usable, so use with caution.

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;
}

Enums to Replace Multiple Variables

If you using lots of booleans, consider an enum.

A platformer character might be standing, jumping, or falling, but never all three at once. Instead of having 3 separate booleans to constantly manage, you can use an enum:

Enum PlayerState
{
      Grounded,
      Jumping,
      Falling
}
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;
    }       
}

Now you only have one variable to track.

The Not Operator

The not operator can be used to change the state of something to it’s opposite value; if it is true, it will make it false:

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

The flashlight is either enabled or it isn’t. What’s the opposite of off? On. By putting in front of the variable, you are saying, become the opposte value of what you are now. 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;

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();

It’s cleaner and easier to read because it saves all those lines of code. What isn’t needed isn’t there. Your eyes only see the important information. 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 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. 

2 thoughts on “Line Saving Code Tips – C#

Add yours

Leave a comment

Blog at WordPress.com.

Up ↑