From f9c3c68e79920c3730e6a20c84d18cdb514508a2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 29 Sep 2026 13:32:47 +0000 Subject: [PATCH] Add README for C# Slice-with-Lambda demo examples (ramp, table, mechanics links) --- .../exercise/csharp/README.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 ideas/split-loop-with-lambda/exercise/csharp/README.md diff --git a/ideas/split-loop-with-lambda/exercise/csharp/README.md b/ideas/split-loop-with-lambda/exercise/csharp/README.md new file mode 100644 index 0000000..9fe3f3a --- /dev/null +++ b/ideas/split-loop-with-lambda/exercise/csharp/README.md @@ -0,0 +1,43 @@ +# 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 readB = a => ...` | `int c = a + b; return c * 2;` | +| `WeatherStation.cs` | `if (_wateredToday)` | `_lightSensor.Read()` (byte) | `Func readLight = () => ...` | sunny -> `WateringDuration.Medium`, shady -> `Short` (reading > 128 => `SunExposure.Sunny`) | +| `IceCreamShop.cs` | `if (_thawedToday)` | `_thermometer.Read()` (byte) | `Func 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`) 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. \ No newline at end of file