Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="$(CommonTestPath)\System\Collections\DictionaryExtensions.cs">
<Compile Include="$(CommonTestPath)\System\Collections\DictionaryExtensions.cs" Condition="'$(TargetGroup)'!='netcoreapp'">
<Link>Common\System\Collections\DictionaryExtensions.cs</Link>
</Compile>
<!-- Common Collections tests -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'uap-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="$(CommonTestPath)\System\Collections\DictionaryExtensions.cs">
<Compile Include="$(CommonTestPath)\System\Collections\DictionaryExtensions.cs" Condition="'$(TargetGroup)'!='netcoreapp' And '$(TargetGroup)'!='uap'">
<Link>Common\System\Collections\DictionaryExtensions.cs</Link>
</Compile>
<Compile Include="BadHasher.cs" />
Expand Down
3 changes: 3 additions & 0 deletions src/System.Collections/ref/System.Collections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public static class CollectionExtensions

public static TValue GetValueOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key) { throw null; }
public static TValue GetValueOrDefault<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue) { throw null; }

public static bool TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value) { throw null; }
public static bool Remove<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, out TValue value) { throw null; }
}
public abstract partial class Comparer<T> : System.Collections.Generic.IComparer<T>, System.Collections.IComparer
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,38 @@ public static TValue GetValueOrDefault<TKey, TValue>(this IReadOnlyDictionary<TK
TValue value;
return dictionary.TryGetValue(key, out value) ? value : defaultValue;
}

public static bool TryAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
if (dictionary == null)
{
throw new ArgumentNullException(nameof(dictionary));
}

if (!dictionary.ContainsKey(key))
{
dictionary.Add(key, value);
return true;
}

return false;
}

public static bool Remove<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, out TValue value)
{
if (dictionary == null)
{
throw new ArgumentNullException(nameof(dictionary));
}

if (dictionary.TryGetValue(key, out value))
{
dictionary.Remove(key);
return true;
}

value = default(TValue);
return false;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't ever removing the value from the dictionary.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(which also highlights that the new tests are missing verification that the value is actually removed)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent point... d'oh. Fixed. 👍

}
}
65 changes: 65 additions & 0 deletions src/System.Collections/tests/Generic/CollectionExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,70 @@ public void GetValueOrDefault_NullIReadOnlyDictionary_ThrowsArgumentNullExceptio
Assert.Throws<ArgumentNullException>("dictionary", () => dictionary.GetValueOrDefault("key"));
Assert.Throws<ArgumentNullException>("dictionary", () => dictionary.GetValueOrDefault("key", "value"));
}

[Fact]
public void TryAdd_NullIDictionary_ThrowsArgumentNullException()
{
IDictionary<string, string> dictionary = null;
Assert.Throws<ArgumentNullException>("dictionary", () => dictionary.TryAdd("key", "value"));
}

[Fact]
public void TryAdd_NullKeyIDictionary_ThrowsArgumentNullException()
{
IDictionary<string, string> dictionary = new SortedDictionary<string, string>();
Assert.Throws<ArgumentNullException>("key", () => dictionary.TryAdd(null, "value"));
}

[Fact]
public void TryAdd_KeyDoesntExistInIDictionary_ReturnsTrue()
{
IDictionary<string, string> dictionary = new SortedDictionary<string, string>();
Assert.True(dictionary.TryAdd("key", "value"));
Assert.Equal("value", dictionary["key"]);
}

[Fact]
public void TryAdd_KeyExistsInIDictionary_ReturnsFalse()
{
IDictionary<string, string> dictionary = new SortedDictionary<string, string>() { ["key"] = "value" };
Assert.False(dictionary.TryAdd("key", "value2"));
Assert.Equal("value", dictionary["key"]);
}

[Fact]
public void Remove_NullIDictionary_ThrowsArgumentNullException()
{
IDictionary<string, string> dictionary = null;
string value = null;
Assert.Throws<ArgumentNullException>("dictionary", () => dictionary.Remove("key", out value));
Assert.Null(value);
}

[Fact]
public void Remove_NullKeyIDictionary_ThrowsArgumentNullException()
{
IDictionary<string, string> dictionary = new SortedDictionary<string, string>();
string value = null;
Assert.Throws<ArgumentNullException>("key", () => dictionary.Remove(null, out value));
Assert.Null(value);
}

[Fact]
public void Remove_KeyExistsInIDictionary_ReturnsTrue()
{
IDictionary<string, string> dictionary = new SortedDictionary<string, string>() { ["key"] = "value" };
Assert.True(dictionary.Remove("key", out var value));
Assert.Equal("value", value);
Assert.Throws<KeyNotFoundException>(() => dictionary["key"]);
}

[Fact]
public void Remove_KeyDoesntExistInIDictionary_ReturnsFalse()
{
IDictionary<string, string> dictionary = new SortedDictionary<string, string>();
Assert.False(dictionary.Remove("key", out var value));
Assert.Equal(default(string), value);
}
}
}
4 changes: 2 additions & 2 deletions src/System.Collections/tests/System.Collections.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<Compile Include="$(CommonTestPath)\System\ObjectCloner.cs">
<Link>Common\System\ObjectCloner.cs</Link>
</Compile>
<Compile Include="$(CommonTestPath)\System\Collections\DictionaryExtensions.cs">
<Compile Include="$(CommonTestPath)\System\Collections\DictionaryExtensions.cs" Condition="'$(TargetGroup)'!='netcoreapp'">
<Link>Common\System\Collections\DictionaryExtensions.cs</Link>
</Compile>
<!-- Generic tests -->
Expand Down Expand Up @@ -161,4 +161,4 @@
</Compile>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
</Project>