Skip to content

Commit e746d9f

Browse files
Update dictionary value sample: .NET 10, TryAdd, GetValueRefOrAddDefault, AddOrUpdate (#2272)
Retarget both projects to net10.0, move to the MSTest 4.5.1 meta package, make Toppings get-only, add AddToppingIfMissing (TryAdd) and AddToppingsByRef (CollectionsMarshal.GetValueRefOrAddDefault), fix the jalapeno spelling, make Program.cs print the article's output sequence, and add a ConcurrentDictionary.AddOrUpdate demonstration. Three new tests (5 total).
1 parent a203444 commit e746d9f

5 files changed

Lines changed: 87 additions & 16 deletions

File tree

‎collections-dictionary/UpdateDictionaryValue/Tests/Tests.csproj‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net7.0</TargetFramework>
4+
<TargetFramework>net10.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77

88
<IsPackable>false</IsPackable>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
13-
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
14-
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
15-
<PackageReference Include="coverlet.collector" Version="3.1.2" />
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
13+
<PackageReference Include="MSTest" Version="4.5.1" />
14+
<PackageReference Include="coverlet.collector" Version="10.1.0" />
1615
</ItemGroup>
1716

1817
<ItemGroup>

‎collections-dictionary/UpdateDictionaryValue/Tests/UpdateDictionaryValueUnitTests.cs‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Concurrent;
12
using UpdateDictionaryValue;
23

34
namespace Tests
@@ -35,5 +36,41 @@ public void GivenUpdatingNewToppingValue_ThenNewToppingIsAdded()
3536

3637
Assert.AreEqual(12, dictionary.Toppings["mushroom"]);
3738
}
39+
40+
[TestMethod]
41+
public void GivenExistingTopping_WhenAddToppingIfMissing_ThenValueIsUnchanged()
42+
{
43+
var dictionary = new ToppingsDictionary();
44+
45+
dictionary.AddToppingIfMissing("pepperoni", 100);
46+
dictionary.AddToppingIfMissing("mushroom", 2);
47+
48+
Assert.AreEqual(4, dictionary.Toppings["pepperoni"]);
49+
Assert.AreEqual(2, dictionary.Toppings["mushroom"]);
50+
}
51+
52+
[TestMethod]
53+
public void GivenNewAndExistingToppings_WhenAddToppingsByRef_ThenBothAreUpdated()
54+
{
55+
var dictionary = new ToppingsDictionary();
56+
57+
dictionary.AddToppingsByRef("mushroom", 5);
58+
dictionary.AddToppingsByRef("pepperoni", 4);
59+
60+
Assert.AreEqual(5, dictionary.Toppings["mushroom"]);
61+
Assert.AreEqual(8, dictionary.Toppings["pepperoni"]);
62+
}
63+
64+
[TestMethod]
65+
public void GivenConcurrentDictionary_WhenAddOrUpdate_ThenAddsThenUpdates()
66+
{
67+
var toppings = new ConcurrentDictionary<string, int>();
68+
69+
var first = toppings.AddOrUpdate("pepperoni", 4, (_, currentAmount) => currentAmount + 4);
70+
var second = toppings.AddOrUpdate("pepperoni", 4, (_, currentAmount) => currentAmount + 4);
71+
72+
Assert.AreEqual(4, first);
73+
Assert.AreEqual(8, second);
74+
}
3875
}
3976
}
Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,37 @@
1-
using UpdateDictionaryValue;
1+
using System.Collections.Concurrent;
2+
using UpdateDictionaryValue;
23

34
var toppingsDictionary = new ToppingsDictionary();
45
toppingsDictionary.AddToppings("pepperoni", 4);
6+
toppingsDictionary.AddToppings("olive", 3);
7+
8+
PrintToppings(toppingsDictionary);
59

610
try
711
{
8-
toppingsDictionary.Toppings["jalepeno"] = toppingsDictionary.Toppings["jalepeno"] + 1;
12+
// The indexer-only version of AddToppings reads the value before it writes it
13+
toppingsDictionary.Toppings["jalapeno"] = toppingsDictionary.Toppings["jalapeno"] + 1;
914
}
10-
catch (Exception e)
15+
catch (KeyNotFoundException e)
1116
{
12-
Console.WriteLine(e);
17+
Console.WriteLine($"{e.GetType()}: {e.Message}");
1318
}
1419

15-
toppingsDictionary.AddToppings("jalepeno", 1);
20+
toppingsDictionary.AddToppings("jalapeno", 1);
21+
22+
PrintToppings(toppingsDictionary);
23+
24+
var toppings = new ConcurrentDictionary<string, int>();
1625

17-
foreach (var topping in toppingsDictionary.Toppings)
26+
Console.WriteLine(toppings.AddOrUpdate("pepperoni", 4, (_, currentAmount) => currentAmount + 4));
27+
Console.WriteLine(toppings.AddOrUpdate("pepperoni", 4, (_, currentAmount) => currentAmount + 4));
28+
29+
static void PrintToppings(ToppingsDictionary toppingsDictionary)
1830
{
19-
Console.WriteLine($"{topping.Key} = {topping.Value}");
20-
}
31+
foreach (var topping in toppingsDictionary.Toppings)
32+
{
33+
Console.WriteLine($"{topping.Key} = {topping.Value}");
34+
}
35+
36+
Console.WriteLine();
37+
}

‎collections-dictionary/UpdateDictionaryValue/UpdateDictionaryValue/ToppingsDictionary.cs‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
namespace UpdateDictionaryValue
1+
using System.Runtime.InteropServices;
2+
3+
namespace UpdateDictionaryValue
24
{
35
public class ToppingsDictionary
46
{
5-
public Dictionary<string, int> Toppings { get; private set; }
7+
public Dictionary<string, int> Toppings { get; }
68

79
public ToppingsDictionary()
810
{
@@ -25,5 +27,21 @@ public void AddToppings(string toppingType, int amount)
2527
Toppings.Add(toppingType, amount);
2628
}
2729
}
30+
31+
public void AddToppingIfMissing(string toppingType, int amount)
32+
{
33+
if (!Toppings.TryAdd(toppingType, amount))
34+
{
35+
Console.WriteLine($"{toppingType} is already on the pizza.");
36+
}
37+
}
38+
39+
public void AddToppingsByRef(string toppingType, int amount)
40+
{
41+
ref var currentAmount = ref CollectionsMarshal
42+
.GetValueRefOrAddDefault(Toppings, toppingType, out _);
43+
44+
currentAmount += amount;
45+
}
2846
}
2947
}

‎collections-dictionary/UpdateDictionaryValue/UpdateDictionaryValue/UpdateDictionaryValue.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net7.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>

0 commit comments

Comments
 (0)