Lesson 12 — C# Properties

Properties

Properties are C#'s built-in mechanism for controlled access to class data — combining the convenience of fields with the validation power of methods.

CSHARP — Auto-properties
public class Learner {
    // Auto-property — compiler generates a hidden backing field:
    public string Name   { get; set; }
    public int    Age    { get; set; }

    // Read-only outside the class:
    public string Course { get; private set; }

    // Init-only (C# 9+) — set only during initialisation:
    public string Id { get; init; }

    public Learner(string id) { Id = id; }
}

var l = new Learner("L001") { Name = "Thandi", Course = "C#" }; // wait, Course has private set
// Better:
var l2 = new Learner("L002");
l2.Name = "Sipho";
l2.Age  = 21;
// l2.Course = "Java"; // compile error — private set

Full Property with Validation

When you need to validate or compute a value, write the getter and setter explicitly with a backing field.

CSHARP — Full properties with validation
public class Learner {
    private string _name;
    private int    _age;
    private double _mark;

    public string Name {
        get => _name;
        set {
            if (string.IsNullOrWhiteSpace(value))
                throw new ArgumentException("Name cannot be empty.");
            _name = value.Trim();
        }
    }

    public int Age {
        get => _age;
        set {
            if (value < 15 || value > 80)
                throw new ArgumentOutOfRangeException(nameof(Age), $"Age {value} is invalid.");
            _age = value;
        }
    }

    public double Mark {
        get => _mark;
        set {
            if (value < 0 || value > 100)
                throw new ArgumentOutOfRangeException(nameof(Mark), "Mark must be 0-100.");
            _mark = value;
        }
    }

    // Computed property — no backing field:
    public string GradeLabel => Mark switch {
        >= 80 => "Distinction",
        >= 60 => "Merit",
        >= 50 => "Pass",
        _     => "Not yet competent"
    };
}

Using Properties

CSHARP — Usage
var l = new Learner();
l.Name = "Thandi";   // calls the setter — validation runs
l.Age  = 21;
l.Mark = 74.5;

Console.WriteLine(l.GradeLabel); // Merit
Console.WriteLine(l.Mark);       // 74.5

// Setter validation:
try { l.Mark = 150; }
catch (ArgumentOutOfRangeException ex) {
    Console.WriteLine(ex.Message); // Mark must be 0-100.
}

Practice Task

Your Turn

Convert your Product class to use full properties: Name validates non-empty, Price (decimal) rejects negatives, Category defaults to "General" if null/empty, Stock (int) rejects negatives. Add a computed IsExpensive bool property returning true if price > 500. Test all validation paths.

Common Mistakes

  • Public fields instead of properties — always prefer properties in production C# code.
  • get; set; when the property should be read-only outside — use get; private set;.
  • Auto-properties cannot validate — you need a backing field for that.
  • Inside a setter, the incoming value is value — this is an implicit parameter name.

Professional Tip

Properties are one of the most important C# features. They look like fields when you use them but behave like methods — validation runs transparently. This is a genuine ergonomic improvement over Java's explicit getters and setters.

Mini Quiz

What is the implicit parameter name inside a C# property setter?