Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions Extensions.Test/DictionaryExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,52 @@ public void GetOrCreateShouldAddAndReturnDefaultValue()
Assert.AreEqual(99, dictionary["key1"]);
}

// The overloads that take a default value never construct one, so they must not demand a
// parameterless constructor. Strings and interfaces have none, and these tests would not compile
// if the constraint came back.

[TestMethod]
public void GetOrCreateWithDefaultShouldAcceptAStringValue()
{
Dictionary<int, string> dictionary = [];

Assert.AreEqual("one", dictionary.GetOrCreate(1, "one"));
Assert.AreEqual("one", dictionary.GetOrCreate(1, "uno"));
Assert.HasCount(1, dictionary);
}

[TestMethod]
public void GetOrCreateWithDefaultShouldAcceptAnInterfaceValue()
{
Dictionary<int, IList<int>> dictionary = [];
List<int> first = [1];

Assert.AreSame(first, dictionary.GetOrCreate(1, first));
Assert.AreSame(first, dictionary.GetOrCreate(1, []));
Assert.HasCount(1, dictionary);
}

[TestMethod]
public void GetOrCreateConcurrentDictionaryWithDefaultShouldAcceptAStringValue()
{
ConcurrentDictionary<int, string> dictionary = new();

Assert.AreEqual("one", dictionary.GetOrCreate(1, "one"));
Assert.AreEqual("one", dictionary.GetOrCreate(1, "uno"));
Assert.HasCount(1, dictionary);
}

[TestMethod]
public void GetOrCreateConcurrentDictionaryWithDefaultShouldAcceptAnInterfaceValue()
{
ConcurrentDictionary<int, IList<int>> dictionary = new();
List<int> first = [1];

Assert.AreSame(first, dictionary.GetOrCreate(1, first));
Assert.AreSame(first, dictionary.GetOrCreate(1, []));
Assert.HasCount(1, dictionary);
}

[TestMethod]
public void GetOrCreateConcurrentDictionaryShouldReturnExistingValue()
{
Expand Down
4 changes: 2 additions & 2 deletions Extensions/DictionaryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@
/// <param name="key">The key to get the value for.</param>
/// <param name="defaultValue">The default value to add when an existing value is not found.</param>
/// <returns>The value for the key if it exists, otherwise a new value.</returns>
public static TVal GetOrCreate<TKey, TVal>(this IDictionary<TKey, TVal> dictionary, TKey key, TVal defaultValue) where TKey : notnull where TVal : notnull, new()
public static TVal GetOrCreate<TKey, TVal>(this IDictionary<TKey, TVal> dictionary, TKey key, TVal defaultValue) where TKey : notnull where TVal : notnull
{
#pragma warning disable KTSU0004 // Use Ensure.NotNull instead of manual null check
if (dictionary is null)
{
throw new ArgumentNullException(nameof(dictionary), "The dictionary cannot be null.");

Check warning on line 36 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The dictionary cannot be null.' 4 times.

Check warning on line 36 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The dictionary cannot be null.' 4 times.

Check warning on line 36 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The dictionary cannot be null.' 4 times.

Check warning on line 36 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The dictionary cannot be null.' 4 times.

Check warning on line 36 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The dictionary cannot be null.' 4 times.

Check warning on line 36 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The dictionary cannot be null.' 4 times.
}
#pragma warning restore KTSU0004 // Use Ensure.NotNull instead of manual null check

#pragma warning disable KTSU0004 // Use Ensure.NotNull instead of manual null check
if (key is null)
{
throw new ArgumentNullException(nameof(key), "The key cannot be null.");

Check warning on line 43 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The key cannot be null.' 4 times.

Check warning on line 43 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The key cannot be null.' 4 times.

Check warning on line 43 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The key cannot be null.' 4 times.

Check warning on line 43 in Extensions/DictionaryExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze & Release

Define a constant instead of using this literal 'The key cannot be null.' 4 times.
}
#pragma warning restore KTSU0004 // Use Ensure.NotNull instead of manual null check

Expand Down Expand Up @@ -98,7 +98,7 @@
/// <param name="key">The key to get the value for.</param>
/// <param name="defaultValue">The default value to add when an existing value is not found.</param>
/// <returns>The value for the key if it exists, otherwise a new value.</returns>
public static TVal GetOrCreate<TKey, TVal>(this ConcurrentDictionary<TKey, TVal> dictionary, TKey key, TVal defaultValue) where TKey : notnull where TVal : new()
public static TVal GetOrCreate<TKey, TVal>(this ConcurrentDictionary<TKey, TVal> dictionary, TKey key, TVal defaultValue) where TKey : notnull
{
#pragma warning disable KTSU0004 // Use Ensure.NotNull instead of manual null check
if (dictionary is null)
Expand Down
Loading