List<T> and IReadOnlyList<T>
“How does a List of a base type hold different objects, and why return IReadOnlyList?”
A list holds references to objects. A list of Contract can hold Loans and Leases side by side, and a loop calls each one's own method.
See it
1/9Before. One variable per contract. But how many contracts are due today? 3? 30,000?
In plain words
holds any number of items and grows as you . T is a placeholder: you write the real type in the angle brackets, like . For classes, the list holds references, so a list of Contract can point at Loan and Lease objects side by side. A loop visits each one, and a call runs each object's own version. When you give a list to other code, give so it can read but not change it.
- is a generic collection (it works for whatever type you put in
<>) that grows as needed; it keeps its items in an array inside. T is fixed when you build, so no casting is needed. - A stores references, so it can hold any derived type. Looping it and calling a virtual method dispatches to each object's override: that is polymorphism in practice.
- I expose collections as (or if callers only loop), so callers cannot or the class's internal list.
- Read-only is a view, not a copy: if the owner changes the list, readers see it. For a snapshot, copy with .
In the lending API
Building a mixed list, looping it, and handing it out safely. Press Next line to walk through them.
Lending.sln · where these 2 files sit
- src/Billing/
<> says what it holds. It starts empty (Count 0) and grows.What they ask next
Interviewers check that you can explain every line. Tap a question to open it.
Array vs List?
An array has a fixed size set when it is built. A grows: inside, it keeps an array and, when full, copies everything into one twice as big. If you know the size up front,
new List<Contract>(30000)skips those copies.Can someone still change an ?
They could cast it back to , since it is the same object underneath. To block even that, return
_items.AsReadOnly(), a wrapper that throws on change.Why not ?
only promises "you can loop me". Fine when callers only loop. also gives and index access (
items[0]) without the risk of a second loop re-running a database query.What happens if you change a list inside its own foreach?
Calling or on the list being looped throws on the next turn. Loop over a copy () or collect the changes and apply them after.
Traps
- Don't say
A can only hold Contract objects, not Loans.SayIt holds references to anything that is a Contract, so Loans and Leases fit. - Don't say
makes a frozen copy.SayIt is a read-only view of the same list. Changes by the owner show through.