Skip to content

Commit 139d797

Browse files
authored
Add a polyfill for Dictionary{TKey,}.TryAdd (#211)
1 parent d2e4048 commit 139d797

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ The class `Polyfill` includes the following extension methods:
512512

513513
#### Dictionary<TKey,TValue>
514514

515+
* `Boolean TryAdd<TKey, TValue>(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.tryadd)
515516
* `Boolean Remove<TKey, TValue>(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove)
516517

517518

src/Consume/Consume.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ class Consume
122122
dictionary.GetValueOrDefault("key");
123123
dictionary.GetValueOrDefault("key", "default");
124124

125+
dictionary.TryAdd("key", "value");
126+
125127
var concurrentDictionary = new ConcurrentDictionary<string, int>();
126128

127129
var value = concurrentDictionary.GetOrAdd("Hello", (_, arg) => arg.Length, "World");

src/Polyfill/Polyfill_Dictionary.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,37 @@ static partial class Polyfill
2323
public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> target) =>
2424
new(target);
2525
#endif
26+
27+
#if NETFRAMEWORK || NETSTANDARD2_0
28+
29+
/// <summary>
30+
/// Attempts to add the specified key and value to the dictionary.
31+
/// </summary>
32+
/// <param name="key">The key of the element to add.</param>
33+
/// <param name="value">The value of the element to add. It can be <see langword="null"/>.</param>
34+
/// <returns><c>true</c> if the key/value pair was added to the dictionary successfully; otherwise, <c>false</c>.</returns>
35+
/// <exception cref="ArgumentNullException"><paramref name="key"/> is <see langword="null"/>.</exception>
36+
[Link("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.tryadd")]
37+
public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> target, TKey key, TValue value)
38+
{
39+
if (key is null)
40+
{
41+
throw new ArgumentNullException(nameof(key));
42+
}
43+
44+
if (!target.ContainsKey(key))
45+
{
46+
target.Add(key, value);
47+
return true;
48+
}
49+
50+
return false;
51+
}
52+
53+
#endif
54+
2655
#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2X
56+
2757
/// <summary>
2858
/// Removes the value with the specified key from the <see cref="Dictionary{TKey,TValue}"/>, and copies the element
2959
/// to the value parameter.
@@ -44,5 +74,6 @@ public static bool Remove<TKey, TValue>(
4474
target.TryGetValue(key, out value);
4575
return target.Remove(key);
4676
}
77+
4778
#endif
48-
}
79+
}

src/Tests/PolyfillTests_Dictionary.cs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ partial class PolyfillTests
33
[Test]
44
public void IReadOnlyDictionaryAsReadOnly()
55
{
6-
IDictionary<string, string> dictionary = new Dictionary<string,string>
6+
IDictionary<string, string> dictionary = new Dictionary<string, string>
77
{
88
{"key", "value"}
99
};
@@ -12,10 +12,40 @@ public void IReadOnlyDictionaryAsReadOnly()
1212
Assert.AreEqual("value", readOnly["key"]);
1313
}
1414

15+
[Test]
16+
public void Dictionary_TryAdd_ThrowsOnNullKey()
17+
{
18+
var dictionary = new Dictionary<string, int>();
19+
20+
Assert.Throws<ArgumentNullException>(() => dictionary.TryAdd(null!, 1));
21+
}
22+
23+
[Test]
24+
public void Dictionary_TryAdd_ReturnsTrueOnSuccessfulAdd()
25+
{
26+
var dictionary = new Dictionary<string, string>();
27+
28+
var entryAdded = dictionary.TryAdd("key", "value");
29+
30+
Assert.True(entryAdded);
31+
Assert.AreEqual("value", dictionary["key"]);
32+
}
33+
34+
[Test]
35+
public void Dictionary_TryAdd_ReturnsFalseIfElementAlreadyPresent()
36+
{
37+
var dictionary = new Dictionary<string, string>() { { "existingKey", "original value" } };
38+
39+
var entryAdded = dictionary.TryAdd("existingKey", "new value");
40+
41+
Assert.False(entryAdded);
42+
Assert.AreEqual("original value", dictionary["existingKey"]);
43+
}
44+
1545
[Test]
1646
public void Dictionary_Remove()
1747
{
18-
var dictionary = new Dictionary<string, string?> { {"key", "value"} };
48+
var dictionary = new Dictionary<string, string?> { { "key", "value" } };
1949

2050
Assert.True(dictionary.Remove("key", out var value));
2151
Assert.AreEqual("value", value);

0 commit comments

Comments
 (0)