Files
learning-hour-maker/ideas/split-loop-with-lambda/exercise/csharp/README.md
T

43 lines
2.1 KiB
Markdown

# Slice with Lambda — C# demo examples
Three C# demo examples for the **Slice with Lambda** refactoring.
Condensed mechanics: https://www.sammancoaching.org/refactorings/slice.html
(where that page says mock, we use a lambda instead).
Full Java walkthrough: `../../storyboard/storyboard.md`.
## The three examples
| file | guard (client state) | unwanted dependency | lambda | tail |
|---|---|---|---|---|
| `MetaphorFree.cs` | `if (a < 0) return 0;` | `_someDependency.mightThrowWhenPreconditionNotSatisfied(a)` | `Func<int, int> readB = a => ...` | `int c = a + b; return c * 2;` |
| `WeatherStation.cs` | `if (_wateredToday)` | `_lightSensor.Read()` (byte) | `Func<byte> readLight = () => ...` | sunny -> `WateringDuration.Medium`, shady -> `Short` (reading > 128 => `SunExposure.Sunny`) |
| `IceCreamShop.cs` | `if (_thawedToday)` | `_thermometer.Read()` (byte) | `Func<byte> readTemperature = () => ...` | warm -> `ThawAmount.Medium`, cold -> `Low` (temperature > 25 => `Warmth.Warm`) |
In all three, the guard reads client state (a parameter or a flag the client
owns), so it stays in the extracted method. Only the dependency call moves
into the lambda.
## The ramp
`MetaphorFree.cs` is the smallest possible shape: no loop, one dependency
call, a tail of one arithmetic step. It carries the capture-to-parameter
lesson: the lambda takes `a` as its parameter (`readB(a)`) because a lambda
moved up into the function head cannot capture method parameters. Its
step-4 stub tests include a throwing stub.
`WeatherStation.cs` and `IceCreamShop.cs` are same-shape domain
repetitions — guard, one dependency call, map to enum, constant tail — so
participants can practice extracting the lambda twice. The C# delegate
syntax (`Func<byte>`) is worth the repetition.
## Same three regions every time
Each example deliberately has the same three regions:
- **before**: guard clauses
- **middle**: one dependency call
- **after**: tail that depends on the value the dependency produced
Matching the pattern: extract the dependency-using code into a lambda,
slide the definition to the top, extract the method below it, pass the
lambda as parameter, test with pure lambda stubs.