Full Properties with Backing Fields
Add logic to getters and setters.
Full Properties with Backing Fields is a free C# Academy lesson on CoddyKit. This is lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 4 lessons in total.
Beyond Auto-Properties
When you need logic inside get or set, you write a full property with an explicit backing field. The field stores the data; the accessors control access.
using System;
class Temperature
{
private double _celsius;
public double Celsius
{
get { return _celsius; }
set { _celsius = value; }
}
}
class Program
{
static void Main()
{
var t = new Temperature();
t.Celsius = 21.5;
Console.WriteLine(t.Celsius);
}
}The Backing Field Convention
By convention, a backing field is private and named with a leading underscore, like _name. The public property exposes it.
using System;
class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
}
class Program
{
static void Main()
{
var p = new Person();
p.Name = "Grace";
Console.WriteLine(p.Name);
}
}The value Keyword
Inside a set accessor, the implicit parameter value holds the incoming assignment. You decide what to do with it.
using System;
class Box
{
private int _size;
public int Size
{
get { return _size; }
set { _size = value * 2; }
}
}
class Program
{
static void Main()
{
var box = new Box();
box.Size = 10;
Console.WriteLine("Stored size: " + box.Size);
}
}Validation in the Setter
A common use of a full property is to validate input before storing it, throwing if the value is invalid.
using System;
class Account
{
private decimal _balance;
public decimal Balance
{
get { return _balance; }
set
{
if (value < 0)
throw new ArgumentException("Balance cannot be negative");
_balance = value;
}
}
}
class Program
{
static void Main()
{
var a = new Account();
a.Balance = 500m;
Console.WriteLine("Balance: " + a.Balance);
}
}Computed (Read-Only) Properties
A property with only a get can compute its value from other fields. There is no backing field because nothing is stored.
using System;
class Rectangle
{
private double _width;
private double _height;
public Rectangle(double w, double h)
{
_width = w;
_height = h;
}
public double Area
{
get { return _width * _height; }
}
}
class Program
{
static void Main()
{
var r = new Rectangle(4, 5);
Console.WriteLine("Area: " + r.Area);
}
}Side Effects in Setters
A setter can do more than store: it can normalize input, update related state, or log changes.
using System;
class User
{
private string _email;
public string Email
{
get { return _email; }
set { _email = value.Trim().ToLower(); }
}
}
class Program
{
static void Main()
{
var u = new User();
u.Email = " Hello@Example.COM ";
Console.WriteLine("Normalized: " + u.Email);
}
}Lazy Computation in a Getter
A getter can cache an expensive result in a backing field the first time it is requested.
using System;
class Report
{
private string _cached;
public string Content
{
get
{
if (_cached == null)
_cached = "Generated at runtime";
return _cached;
}
}
}
class Program
{
static void Main()
{
var r = new Report();
Console.WriteLine(r.Content);
Console.WriteLine(r.Content);
}
}Guarding Against Bad State
Combine a backing field with logic to keep an object always valid. Here the setter clamps the value into a range.
using System;
class Volume
{
private int _level;
public int Level
{
get { return _level; }
set
{
if (value < 0) _level = 0;
else if (value > 100) _level = 100;
else _level = value;
}
}
}
class Program
{
static void Main()
{
var v = new Volume();
v.Level = 150;
Console.WriteLine("Clamped: " + v.Level);
}
}Combining Stored and Computed
A class often mixes stored properties (with backing fields) and computed read-only properties derived from them.
using System;
class Employee
{
private string _first;
private string _last;
public string First { get { return _first; } set { _first = value; } }
public string Last { get { return _last; } set { _last = value; } }
public string FullName { get { return _first + " " + _last; } }
}
class Program
{
static void Main()
{
var e = new Employee { First = "Marie", Last = "Curie" };
Console.WriteLine(e.FullName);
}
}Raising Change Notifications
Setters are the natural place to notify when data changes, a pattern used heavily in UI frameworks.
using System;
class Model
{
private int _count;
public int Count
{
get { return _count; }
set
{
if (_count != value)
{
_count = value;
Console.WriteLine("Count changed to " + _count);
}
}
}
}
class Program
{
static void Main()
{
var m = new Model();
m.Count = 1;
m.Count = 1;
m.Count = 2;
}
}Putting It Together
Full properties let a class enforce invariants and expose derived data, all behind a clean field-like interface.
using System;
class Thermostat
{
private double _target;
public double Target
{
get { return _target; }
set { _target = value < 10 ? 10 : value; }
}
public string Status { get { return _target >= 22 ? "Warm" : "Cool"; } }
}
class Program
{
static void Main()
{
var th = new Thermostat();
th.Target = 5;
Console.WriteLine(th.Target + " -> " + th.Status);
th.Target = 24;
Console.WriteLine(th.Target + " -> " + th.Status);
}
}Quick Check
Test your understanding of full properties.
Recap
A full property pairs a private backing field with explicit get/set accessors so you can add validation, normalization, caching, or change notifications. Read-only computed properties have only a getter and no backing field. The value keyword carries the incoming assignment in a setter.
using System;
class Demo
{
private int _n;
public int N
{
get { return _n; }
set { _n = value < 0 ? 0 : value; }
}
public int Doubled { get { return _n * 2; } }
}
class Program
{
static void Main()
{
var d = new Demo();
d.N = -5;
Console.WriteLine(d.N + ", " + d.Doubled);
}
}Learn C# with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 93
- Lessons
- 346
Frequently Asked Questions
Is the “Full Properties with Backing Fields” lesson free?
Yes — the full text of “Full Properties with Backing Fields” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO. The C# Academy course includes 4 lessons in total.
What will I learn in “Full Properties with Backing Fields”?
Add logic to getters and setters. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start C# Academy?
No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 2 of 4.
How long does the “Full Properties with Backing Fields” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this C# Academy lesson?
Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Auto-Implemented Properties
- Full Properties with Backing Fields
- Expression-Bodied Members
- Indexers