<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. C#
  3. Object-oriented programming
All lessons in this course

Lesson 19 of 60 14 minIntermediate

Fields and properties

Protect an object’s data with properties: get and set accessors, validation, auto-properties, read-only, computed and init-only properties.

With public fields, any code anywhere can write beam.Length = -50; and your object is broken. Properties look like fields from the outside, but run code when they are read (get) or written (set), so the class stays in control of its data.

Interactive

A property is a guarded door to a field

Outside code can’t touch _length directly. It must go through the Length property, whose set checks the value. Try 7.5, 0, -3 or 45.

Beam.cs
class Beam{    private double _length = 6;          // backing field     public double Length    {        get => _length;        set        {            if (value <= 0 || value > 30)                throw new ArgumentOutOfRangeException(nameof(value));            _length = value;        }    }     public double KgPerMetre { get; set; } = 22.4;   // auto-property     public double WeightKg => Length * KgPerMetre;   // computed}
beam object
_length6private field
Length6property (get/set)
WeightKg134.4read-only, calculated
The object starts with _length = 6. Change it only through the property.

A full property with a backing field

Beam.cs
public class Beam{    private double _length;            // private: only this class can touch it     public double Length    {        get { return _length; }        // runs when someone reads beam.Length        set                            // runs on beam.Length = x        {            if (value <= 0)            // 'value' is the new value being assigned                throw new ArgumentOutOfRangeException(nameof(value));            _length = value;        }    }} var b = new Beam();b.Length = 7.5;                        // calls set with value = 7.5Console.WriteLine(b.Length);           // calls get
Output
7.5

Auto-properties

When you don’t need any logic, let the compiler create the hidden backing field for you:

Auto.cs
public class Column{    public string Mark { get; set; } = "C1";     // default value    public double Height { get; set; }    public string Grade { get; private set; } = "S355";   // anyone reads, only the class writes}

Even without logic, prefer auto-properties to public fields: you can add validation later without changing any code that uses the class.

Read-only and computed properties

Computed.cs
public class Rectangle{    public double Width { get; }        // get-only: set in the constructor, then fixed    public double Height { get; }     public Rectangle(double w, double h) { Width = w; Height = h; }     public double Area => Width * Height;        // computed on every read    public bool IsSquare => Width == Height;} var r = new Rectangle(3, 3);Console.WriteLine($"{r.Area} {r.IsSquare}");
Output
9 True

init-only setters

Init.cs
public class Point{    public double X { get; init; }    public double Y { get; init; }} var p = new Point { X = 2, Y = 5 };   // allowed: during creation// p.X = 10;                          // error CS8852: init-only

init lets callers set the value with an object initialiser, but never change it afterwards. Objects that can’t change (immutable objects) are easier to reason about and safe to share.

Which one to use?

NeedWrite
Simple data, may changepublic T Name { get; set; }
Set once at creationpublic T Name { get; init; } or { get; } + constructor
Readable by all, changed only insidepublic T Name { get; private set; }
Rules on the valuefull property with a private backing field
Derived from other datapublic T Name => expression;
Internal stateprivate field
Quick check

Inside a set accessor, what is value?

Quick check

Which property can be read by anyone but only changed inside its own class?

Practice

Create a class Temperature with a property Celsius that rejects values below -273.15 (absolute zero), and a computed read-only property Fahrenheit (C × 9 / 5 + 32). Set 25 °C and print both.

Show the solution
Solution.cs
public class Temperature{    private double _celsius;     public double Celsius    {        get => _celsius;        set        {            if (value < -273.15)                throw new ArgumentOutOfRangeException(nameof(value), "Below absolute zero.");            _celsius = value;        }    }     public double Fahrenheit => Celsius * 9 / 5 + 32;} var t = new Temperature { Celsius = 25 };Console.WriteLine($"{t.Celsius} °C = {t.Fahrenheit} °F");
Output
25 °C = 77 °F

Remember

  • Properties look like fields but run get/set code.
  • Keep fields private; expose data through properties.
  • Auto-properties: { get; set; }; restrict with private set or init.
  • Computed properties (=> expression) are always up to date.
0 of 60 lessons completed