Getter method vs inline lambda

@Brian_Trotter I’m working through some refactoring as i merge projects into the RPG course. Obviously high up on this list is closing down publics in some of my older code. I’m curious if there is any difference between an inline passthrough with a get method and an inline lambda( other than syntax). is there any best practice here . does one cache and the other compute on call etc.

EX

in one script

[SerializeField] CharacterSet enemySet;
public CharacterSet GetEnemySet() { return enemySet; }

called like this in another script

GameManager.currentEnemySet = encounter.GetEnemySet();

vs

[SerializeField] CharacterSet enemySet;
public CharacterSet EnemySet => enemySet;

called like this in another script

    GameManager.currentEnemySet = encounter.EnemySet;

P.S. Ill probably refactor this specific example to an event called when the battlefield is being set up. i know it looks a bit silly now. I’m just re-wrapping my head around some old code for the time being, and didn’t know if there were use cases or best practice cases i should be aware of when it comes to getter method vs lambda.

It’s really the same thing. I believe ‘getter’ and ‘setter’ methods came from a time when there weren’t ‘properties’ and developers wanted to restrict access to fields. I could be wrong, I don’t really know the history.

The expression bodied property

[SerializedField] private CharacterSet enemySet;
public CharacterSet EnemySet => enemySet;

is the same as

[SerializedField] private CharacterSet enemySet;
public CharacterSet EnemySet
{
    get
    {
        return enemySet;
    }
}

which, in turn, is essentially the same as

[SerializedField] private CharacterSet enemySet;
public CharacterSet GetEnemySet()
{
    return enemySet;
}
// or with an expression-bodied method
[SerializedField] private CharacterSet enemySet;
public CharacterSet GetEnemySet() => enemySet;
1 Like

All of these, including the existence of properties in the first place are examples of Syntatic Sugar.

In the earliest OOP, accessors were always

private int myVariable;
public int GetMyVariable()
{
    return myVariable;
}

private void SetMyVariable(int value)
{
    myVariable = value;
}

Then along came the idea of properties, which have the incredible advantage of, when there is a setter, being able to use the variable in virtually any assignment you can think of.

private int myVariable;
public int MyVariable
{
    get
    {
         return myVariable;
    }
    private set
    {
         myVariable = value;
    }
}

With this, you can do things like

MyVariable+=someChange;

in code.

A quick note here before I carry on: You’ll note that I used private setters here. You’ll often see programmers who create properties with public getters and setters… if those setters don’t do something besides setting the value of the backing field, then they are just creating getters and setters for the sake of creating getters and setters and should just use public variables (which, IMO, is bad form).
So

private int score;
public int GetScore()
{
    return score;
}
public void SetScore(int value)
{
    score = value;
}

is just an end run around using public int Score; in the first place.
Now if you did

public void SetScore(int value)
{
    if(value<0) return;
    if(value > 100) TriggerWinCondition();
    score=value;
}

Then this is a different matter, and control over the value is still in the hands of the containing class.

The => operator (in this case, referred to as expression bodied syntax) is used with a getter or a setter, whatever follows must be functionally one line of code. On a getter, or without get;set; at all, it basically functions as “return”

so

private int myVariable;
public int MyVariable => myVariable;

is the exact same as

private int myVariable;
pubic int MyVariable
{
    get
    {
         return myVariable;
    }
}

In fact, under the hood, when the compiler converts C# into the CLR or into C++ with IL2CPP, the compiler will create methods to represent the getters (and setters, when applicable).

You can also use => with setters if the method is one line.

public int MyVariable
{
     get=>myVariable;
     private set=>myVariable = value;
}

In newer versions of C# and Unity, you can use autoproperties. In this case the compiler creates a hidden backing field, and you don’t have to worry about it. This is almost exclusively used for this construction:

public int MyValue {get; private set;}

In this case, a hidden backing field is created, and a generic getter and setter is created. Note that this autoproperty will not work with custom getters and setters, and under the hood is equivalent to the

private int myBackingField;
public int MyValue
{    
     get=>myBackignField;
     set=>myBackingField = value;
}
3 Likes

thank you both for the great explanations. I figured it was just syntax but thought it foolish not to at least check before doing a whole ton of work. i think we need to start a signature campaign to change Brian’s title to “Game Development Mentor and resident code historian”.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms