Fields and properties
Protect an object’s data with properties: get and set accessors, validation, auto-properties, read-only, computed and init-only properties.
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.
A full property with a backing field
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 get7.5
Auto-properties
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}Read-only and computed properties
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}");9 True
init-only setters
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-onlyinit 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?
| Need | Write |
|---|---|
public T Name { get; set; } | |
public T Name { get; init; } or { get; } + constructor | |
public T Name { get; private set; } | |
public T Name => expression; | |
private field |
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
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");25 °C = 77 °F
Remember
Properties look like fields but run get/setcode.Keep fields private; expose data through properties.Auto-properties: { get; set; }; restrict withprivate setorinit.Computed properties ( => expression) are always up to date.