0Pricing
C# Academy · Lesson

Full Properties with Backing Fields

Add logic to getters and setters.

Full Properties with Backing Fields is a free C# Academy lesson on CoddyKit — 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, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

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);
    }
}

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, and the C# Academy course includes 4 lessons in total. 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.

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; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

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

  1. Auto-Implemented Properties
  2. Full Properties with Backing Fields
  3. Expression-Bodied Members
  4. Indexers
← Back to C# Academy