In the previous lesson, we used Private Fields and Public Methods to protect data. It worked, but it was ugly to type:
properties are class members that provide a flexible mechanism to read, write, or compute the value of a private field. They act as “smart fields” that use special methods called accessors to manage data access
Usually, we make variables private to protect them (Encapsulation). However, writing “Getter” and “Setter” methods can make our code bulky and hard to read.
The “clunky” way (Methods)
public int GetPoints() { return points; }
public void SetPoints(int value) { points = value; }
// To use it:
player.SetPoints(100);
The “Clean” Way (Properties)
int private points;
public int Points
{
get { return points; } // This is the GetPoints() method
set { points = value; } // This is the SetPoints() method
}
// To use it:
player.Points += 100; // to set the value.
int playerPoint = player.Points; // to get the value.
What is “value”
IN the Setter method we made earlier, we used a parameter like newAmount:
pulbic void SetPoints (int newAmount) {
points = newAmount;
}
In a Property, C# gives you a built-in variable called value
- Whenever someone writes
player.Points = 100;, C# automatically puts that100into the wordvalue. - You don’t have to create
value; it is just there for you to use inside theset { }block.
private int points;
public int Points
{
get { return points; }
set
{
// We can add a rule here!
if (value < 0) points = 0;
else points = value;
}
}
If a student tries to write player.Points = -50;, the code inside the set block will catch it and change it to 0 automatically. It’s like a smart variable.
Auto-property
public int Points { get; set; }
When you type { get; set; }, the C# compiler is actually very smart. It says: “I see the user wants to store data here. I will secretly create a hidden private variable for them and write the get/set code automatically.”
You don’t see that hidden variable, but it exists in the computer’s memory.
The “Bodyguard” (The Setter) If you just have a variable, any part of your code can “sneak in” and set your points to -50. But with a Property, you can write a rule that catches that mistake and fixes it before it ever touches your actual data.
public int Points
{
get { return _points; }
set
{
// This is your bodyguard checking the ID!
if (value < 0)
{
_points = 0; // Reset to 0 if it's negative
}
else
{
_points = value; // Only save it if it's a good number
}
}
}
if we write player.Points = -50; it will reset to 0
Object Initializer Syntax
When you create an object, you usually use a Constructor (the stuff inside the parentheses ()). This is for the “Mandatory” stuff—things the object must have to exist.
The Initializer (the stuff inside the curly braces { }) is for the “Extra” stuff—the properties you want to set right away without writing 10 lines of code.
The Player Class
class Player
{
// 1. BACKING FIELD (Private - The hidden data)
private int score;
// 2. CONSTRUCTOR (Mandatory - Every player MUST have a name)
public string Name { get; set; } // Auto-property for Name
public Player(string name)
{
Name = name;
}
// 3. FULL PROPERTY (The Bodyguard - Protects the Score)
public int Score
{
get { return score; }
set
{
// If someone tries to set a negative score, we fix it to 0
if (value < 0) score = 0;
else score = value;
}
}
// 4. AUTO-PROPERTY (No rules needed yet)
public int LivesLeft { get; set; }
}
The Comparison Before this existed, if you wanted to create a player and set their stats, it was a multi-step process:
// 1. Create the object
Player p1 = new Player("CatBot 2000");
// 2. Set the properties one by one
p1.Score = 2000;
p1.LivesLeft = 9;
p1.Level = 1;
The “Initializer” Way (Modern C#)
Player p1 = new Player("CatBot 2000")
{
Score = 2000,
LivesLeft = 9,
Level = 1
};
Both codes do the exact same thing, but the second one is much cleaner and groups all the “starting data” together.
How it works with your “Bodyguard” (Properties)
The best part is that even inside these curly braces { }, your Properties are still working!
If you try to do this:
Player p1 = new Player("CatBot 2000") { Score = -500 };
Your Property’s set block will catch that -500, run its “if statement,” and change it to 0 before the object is even finished being created.