# Classes, Constructors and Properties — C#/.NET

Source: https://www.skillbyai.com/en/dotnet/o-classes

> 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.](assets/figures/dotnet/section-3-map.svg) — 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.

```cs
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.

**Quiz:** What does the `required` modifier on a property do?

- [x] 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).
