Properties & Auto-Properties
Objects hold data — but exposing that data as raw public fields gives the outside world unchecked access to your object's insides. Properties are C#'s elegant solution: they look like fields to anyone using them, but secretly run get and set logic so you can validate, compute, or lock down a value. They're the polished public surface of every well-designed class.
Learn Properties & Auto-Properties in our free C# course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free C# course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
A property is like a bank teller standing in front of the vault . The money (the private field) is locked away; you don't reach in yourself. You ask the teller to deposit (the set ) and they check the amount is valid first; you ask for the balance (the get ) and they hand back the right figure. A raw public field is like leaving the vault door open — anyone can shove in any value, valid or not. The teller (property) keeps everything controlled and safe.
1. Auto-Properties
The everyday property is the auto-property : public string Name {' '} . The compiler quietly creates a hidden backing field and the trivial get/set logic. You can also write a computed read-only property with => , which calculates its value from other data every time it's read — like IsAdult => Age >= 18 .
2. Full Properties with Validation
When you need real logic, expand to a full property backed by a private field. Inside the set accessor, the keyword value is the incoming assignment — that's where you validate. This is the whole point of properties: a public field can't reject a bad value, but a property can throw or clamp before the data is ever stored.
Your turn. Give Product two auto-properties and one computed property. The hints in the comments show the exact syntax.
3. Controlling Access
Properties let you tune who can read and write. A private set means outsiders can read the value but only the class itself can change it — perfect for a temperature that must go through validation. A computed property derived from it (Fahrenheit from Celsius) always stays in sync because it's recalculated on every read.
Modern C# adds the init accessor: a property you can set only during object creation (in an object initialiser or constructor), after which it's immutable. It gives you the best of both worlds — flexible construction with object initialisers, but no accidental mutation later. Ideal for IDs and other "set once" data.
A get-only auto-property ( public int Id {' '} ) is even stricter — it can only be assigned in the constructor. Reach for init when you want object-initialiser syntax, and get-only when the value always comes from constructor logic.
These lines declare a Circle class with a computed Area and use it. Order them so the program prints an area of about 78.5 for radius 5.
Why: the class opening brace comes first, then its members ( Radius before Area , though members can appear in any order inside the class), then the closing brace. Radius must be set before Area is read — and because Area is computed, it uses whatever Radius holds at read time: 3.14159 × 25 ≈ 78.5 .
16 — Area is computed as W * W , and 4 * 4 = 16 . It's recalculated each time you read it.
No — the setter is private , so code outside the class can't assign X . Only members of T can set it.
100 — the second assignment throws before _balance is overwritten, so the stored value stays at the last valid one, 100 .
Build a Rectangle with validated Width / Height and computed Area / Perimeter . The outline is in the comments.
Practice quiz
What is the key difference between a field and a property?
- A field runs get/set logic; a property stores data directly
- They are identical
- A property looks like a field but runs get/set methods that can validate or compute
- A property cannot be public
Answer: A property looks like a field but runs get/set methods that can validate or compute. A property looks like a field from outside but is really a pair of get/set accessors that can run logic.
What does an auto-property 'public string Name { get; set; }' do?
- Creates a hidden backing field and trivial get/set for you
- Throws at runtime
- Makes Name read-only
- Requires you to write a backing field
Answer: Creates a hidden backing field and trivial get/set for you. An auto-property tells the compiler to generate a hidden backing field plus the simple get/set logic.
Inside a setter, what does the 'value' keyword represent?
- The previous value
- The backing field name
- A default value
- The incoming assignment being set
Answer: The incoming assignment being set. 'value' is the incoming assignment in a set accessor — that's where you validate before storing it.
What does a computed property like 'public bool IsAdult => Age >= 18;' do?
- Stores a fixed value
- Recalculates from other data each time it's read
- Has a settable backing field
- Runs only once
Answer: Recalculates from other data each time it's read. An expression-bodied computed property has a getter only and is recalculated from other data on each read.
What does 'public double Celsius { get; private set; }' allow?
- Anyone can read it, but only the class can change it
- Anyone can read and write it
- Nobody can read it
- It is immutable forever
Answer: Anyone can read it, but only the class can change it. A private set means outsiders can read the value but only the declaring class can assign it.
What does the 'init' accessor allow?
- Setting the value anytime
- Reading only
- Setting the value only during object creation, then immutable
- Calling a method
Answer: Setting the value only during object creation, then immutable. init lets you set the property in an object initialiser or constructor, after which it is immutable.
Why write 'set => _balance = value;' instead of 'set => Balance = value;'?
- They behave the same
- Assigning the property to itself recurses forever (StackOverflow)
- The field version is read-only
- value is invalid in a setter
Answer: Assigning the property to itself recurses forever (StackOverflow). Assigning the property inside its own setter calls the setter again forever; assign the private backing field instead.
Why prefer a property over a public field in most cases?
- Fields are faster to type
- Fields can validate; properties cannot
- Properties cannot be public
- A property gives a stable public surface you can later add validation to without breaking callers
Answer: A property gives a stable public surface you can later add validation to without breaking callers. Even a simple auto-property lets you later add validation, make the setter private, or compute the value without breaking calling code.
What can a get-only auto-property 'public int Id { get; }' be assigned in?
- Anywhere
- Only the constructor or its initialiser
- Only a setter
- Never
Answer: Only the constructor or its initialiser. A get-only auto-property can only be assigned in the constructor (or field initialiser), making it immutable afterwards.
If a setter throws when value < 0, what is the stored value after 'acc.Balance = 100;' then a rejected 'acc.Balance = -1;'?
- -1
- 0
- 100
- It throws on read
Answer: 100. The second assignment throws before overwriting the backing field, so the last valid value 100 remains.