Lesson 7 / 25

Classes, Constructors and Properties

Design classes with properties, constructors, access modifiers and required members.

Encapsulated state and behaviour

A class groups data (fields and properties) with behaviour (methods). Properties expose data through get and set accessors; auto-properties (public string Name { get; set; }) generate the backing field. Use init accessors for properties that can be set only during object creation, and required to force callers to set them in an object initializer. Constructors set up valid state; primary constructors (C# 12) put parameters on the class declaration itself, available throughout the class body. Access modifiers control visibility: public, private (default for members), protected, internal (same assembly, default for top-level types), protected internal and private protected. Static members belong to the type, not to instances. C# 14 adds the field keyword, which lets a property accessor refer to the compiler-generated backing field, so you can add validation without declaring a field yourself.

An object and its public surface

Private state sits inside; public properties and methods are the only way in.

A rounded box with a solid inner core and a ring of small doorways around its edge, arrows entering only through the doorways.
Figure 3.1 — Encapsulation: private state behind public members.

A bank account with invariants

The balance can change only through methods that check the rules.

public class BankAccount(string owner)
{
    public string Owner { get; } = owner;
    public decimal Balance { get; private set; }
    public required string Ifsc { get; init; }

    public void Deposit(decimal amount)
    {
        ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
        Balance += amount;
    }

    public bool TryWithdraw(decimal amount)
    {
        if (amount <= 0 || amount > Balance) return false;
        Balance -= amount;
        return true;
    }
}

var acct = new BankAccount("Asha") { Ifsc = "SBIN0001234" };
acct.Deposit(5000m);

Public setters leak invariants

If Balance had a public setter, any code could set it to a negative number. Expose operations (Deposit, TryWithdraw) that enforce the rules, and keep setters private or init-only.

Quick check: What does the `required` modifier on a property do?

  • Forces callers to set it when creating the object, or the code does not compile
  • Makes the property read-only forever
  • Validates the value at run time
  • Makes the property static
Answer

Forces callers to set it when creating the object, or the code does not compile — Required members must be initialised in the object initializer (or by a constructor marked SetsRequiredMembers).