Slice with lambda: add C# exercise projects and export
- Add SliceWithLambda.slnx + csproj scaffolding for ideas/slice-with-lambda/ exercise/csharp (examples project + xUnit solution/test project) - Add exercises/slice-with-lambda (C# version of the prefactored-longrange exercise with Buyers and SliceWithLambda projects) - Add export/slice-with-lambda (nested git repo with exercise export) - Ignore bin/ and obj/ build output at repo root
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IceCreamBuyers
|
||||
{
|
||||
public class Buyer
|
||||
{
|
||||
public Buyer(string name, IReadOnlyList<IceCream> favourites)
|
||||
{
|
||||
Name = name;
|
||||
Favourites = favourites;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public IReadOnlyList<IceCream> Favourites { get; }
|
||||
|
||||
public int ScoopsOf(IceCream flavour)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IceCreamBuyers
|
||||
{
|
||||
/// <summary>
|
||||
/// Reference end state of exercise 3 (extract lambda, slide, extract method
|
||||
/// with a function parameter — the pure rep of Slice with Lambda).
|
||||
/// </summary>
|
||||
public class Buyers
|
||||
{
|
||||
private readonly PriceList priceList = new();
|
||||
private readonly List<Buyer> buyers = new()
|
||||
{
|
||||
new("Anke", new List<IceCream> { IceCream.Strawberry, IceCream.Vanilla }),
|
||||
new("Bram", new List<IceCream> { IceCream.Chocolate }),
|
||||
new("Celine", new List<IceCream> { IceCream.Vanilla, IceCream.Chocolate }),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// No-arg overload: callers unchanged, the "real" pricing function baked in.
|
||||
/// </summary>
|
||||
public int ShoppingListTotal(string buyerName)
|
||||
{
|
||||
return ShoppingListTotal(ByName(buyerName), priceList.PriceFor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The seam: the pricing source is injected as a function.
|
||||
/// Testable: pass any pure function instead of calling the pricing service.
|
||||
/// </summary>
|
||||
public int ShoppingListTotal(Buyer buyer, Func<IceCream, int> priceFor)
|
||||
{
|
||||
var total = 0;
|
||||
foreach (var flavour in buyer.Favourites)
|
||||
{
|
||||
total += buyer.ScoopsOf(flavour) * priceFor(flavour);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private Buyer ByName(string name)
|
||||
{
|
||||
return buyers.Find(b => b.Name == name)
|
||||
?? throw new InvalidOperationException($"Unknown buyer {name}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace IceCreamBuyers
|
||||
{
|
||||
public enum IceCream
|
||||
{
|
||||
Strawberry,
|
||||
Chocolate,
|
||||
Vanilla
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace IceCreamBuyers
|
||||
{
|
||||
public class PriceList
|
||||
{
|
||||
// placeholder implementation - real version would call the pricing service
|
||||
private static readonly Dictionary<IceCream, int> BasePrices =
|
||||
new()
|
||||
{
|
||||
{ IceCream.Strawberry, 3 },
|
||||
{ IceCream.Vanilla, 2 },
|
||||
{ IceCream.Chocolate, 4 },
|
||||
};
|
||||
|
||||
public int PriceFor(IceCream flavour)
|
||||
{
|
||||
return BasePrices[flavour] + SurgePricing();
|
||||
}
|
||||
|
||||
private int SurgePricing()
|
||||
{
|
||||
return new Random().Next(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user