c# · level 3 · unit 5 · lesson 4
- meet it
- guess first
- your turn
- fix it
- nailed it
Tap a green word if you get lost.
meet it
Immutable objects cannot change after they are made.
An immutable object is fixed once built. Nobody can change it behind your back, threads can share it safely, and no bug comes from someone quietly editing it. To change something, make a new copy, as records do with with.
Write instead of { get; set; }. An init accessor accepts a value while the object is being created, then locks: a later assignment will not compile. Positional records already work this way.
A list inside is still an open door. Take a when the object is built, and expose it as IReadOnlyList<T>, which has no Add or Remove.
using System;
using System.Collections.Generic;
var stops = new List<string> { "Leeds", "York" };
var route = new Route("Express", stops);
stops.Add("Hull");
Console.WriteLine($"{route.Name}: {string.Join(" > ", route.Stops)}");
var late = route with { Name = "Late express" };
Console.WriteLine($"{late.Name}: {late.Stops.Count} stops");
record Route
{
public string Name { get; init; }
public IReadOnlyList<string> Stops { get; init; }
public Route(string name, List<string> stops)
{
Name = name;
Stops = new List<string>(stops);
}
} A readonly field works like init for fields: it can only be set while the object is being built.
guess first
Someone wants a better seat. What will this show?
Guess before you run it. Wrong guesses are how you learn, and nothing is marked.
using System;
var ticket = new Ticket { Seat = "B12", Price = 30m };
ticket.Seat = "A1";
Console.WriteLine(ticket.Seat);
class Ticket
{
public string Seat { get; init; }
public decimal Price { get; init; }
}
your turn
Your turn. Pay into an account without changing it.
On line 11, make Balance an init property. Then, on line 4, choose your own deposit: with makes a new account and leaves the old one alone.
output
press run to see what happens
fix it
The squad gains a stranger. Can you fix it?
output
press run to see what happens
- The squad gained a player nobody gave it. Which list does
Squadkeep? - Line 15 keeps the caller's own list, so when the caller changes it, the squad changes too.
- Store a defensive copy: change line 15 to
this.players = new List<string>(players);, then run.
nailed it
your objects stay the way you built them. :D
- Immutable objects never change after they are built.
initlocks a property once the object exists.- Copy incoming lists, and hand out
IReadOnlyList<T>.
new words in your collection
- init
- defensive copy
This lesson isn’t saved. A free account remembers every lesson you finish.