Auto-Properties and Read-Only Properties
Write short auto-properties, make a property read-only to the outside with private set or get-only, and calculate a property from others.
Apprentice · C# · OOP · Updated
After this lesson you can
- Write auto-properties, including ones that only the class can set
- Write a calculated property that works out its value from other properties
Key takeaways
{ get; set; }is an auto-property: C# writes the backing field for you. Use it when there's no rule to check.private setlets other code read a property while only the class changes it, as with a team'sWins.- A property with only a
get, such aspublic string Name { get; }, is set in the constructor and never changes after that. - A calculated property, such as
GamesPlayed => Wins + Losses, works its value out each time it's read, so it never disagrees with the others. new Team { Wins = 7, Losses = 3 }is an object initializer: it sets public properties as the object is created.
Most properties don't check anything; they just hold a value. Writing a backing field and a get and set for each one would be a lot of typing for nothing, so C# has a shortcut.
Auto-properties
An auto-property writes the backing field for you:
Team team = new Team();
team.Name = "Georgia";
team.Wins = 7;
Console.WriteLine( quot;{team.Name}: {team.Wins} wins");
public class Team
{
public string Name { get; set; } = "";
public int Wins { get; set; }
}
Georgia: 7 wins
{ get; set; } means "a property anyone can read and set, with a hidden field behind it". = "" gives it a starting value. (A string property needs one, or C# warns that it might be null.)
When you need a rule, as in the last lesson, write the full property. When you don't, use an auto-property: you can always change it to a full one later, and no calling code has to change.
Read-only to the outside: private set
Often other code should be able to read a value, but only the object itself should change it. A team's wins should change only when a game is recorded, not because some other code assigned a number. Make the set private:
Team team = new Team("Georgia");
team.RecordWin();
team.RecordWin();
team.RecordLoss();
Console.WriteLine( quot;{team.Name}: {team.Wins}-{team.Losses}");
public class Team
{
public string Name { get; private set; }
public int Wins { get; private set; }
public int Losses { get; private set; }
public Team(string name)
{
Name = name;
}
public void RecordWin()
{
Wins++;
}
public void RecordLoss()
{
Losses++;
}
}
Georgia: 2-1
Outside the class, team.Wins = 50; doesn't compile. The only way to change the record is through RecordWin and RecordLoss.
A property with only a get, such as public string Name { get; }, can be set only in the constructor, and never again.
Calculated properties
Some values shouldn't be stored at all, because they follow from others. A team's winning percentage comes from its wins and losses. Store it separately and the two can disagree; calculate it, and they never can. A calculated (or derived) property has only a get, which works the value out each time it's read:
Team team = new Team { Wins = 7, Losses = 3 };
Console.WriteLine( quot;Games played: {team.GamesPlayed}");
Console.WriteLine( quot;Winning percentage: {team.WinningPercentage}%");
team.Losses = 7;
Console.WriteLine( quot;Winning percentage now: {team.WinningPercentage}%");
public class Team
{
public int Wins { get; set; }
public int Losses { get; set; }
public int GamesPlayed => Wins + Losses;
public int WinningPercentage
{
get
{
if (GamesPlayed == 0)
{
return 0;
}
return Wins * 100 / GamesPlayed;
}
}
}
Games played: 10
Winning percentage: 70%
Winning percentage now: 50%
=> Wins + Lossesis a short way to write a property with only agetwhose whole job is one expression.- When
Losseschanged,WinningPercentagechanged with it: there's nothing to keep in step.
Setting properties as you create: object initializers
new Team { Wins = 7, Losses = 3 } creates the object and then sets public properties in one statement. The curly braces after new Team are an object initializer. It works for any property with a public set.
Check yourself
2 questions to try on the lesson page.
So what
Choose each property's access on purpose: public get and set for plain values, private set for values only the object should change, and a calculated get for values that follow from others.