From b0718835f920068a5828332811ec918191a075dd Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Thu, 15 Dec 2016 02:17:57 +0700 Subject: [PATCH 1/6] Dictionary.GetValueOrDefault --- .../src/System.Collections.csproj | 5 ++- .../Generic/CollectionExtensions.cs | 33 +++++++++++++++++++ .../System/Collections/Generic/Dictionary.cs | 18 ++++++++-- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs diff --git a/src/System.Collections/src/System.Collections.csproj b/src/System.Collections/src/System.Collections.csproj index 74c95124ed50..3affdd7de58a 100644 --- a/src/System.Collections/src/System.Collections.csproj +++ b/src/System.Collections/src/System.Collections.csproj @@ -86,5 +86,8 @@ + + + - + \ No newline at end of file diff --git a/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs new file mode 100644 index 000000000000..863d003c7264 --- /dev/null +++ b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs @@ -0,0 +1,33 @@ +namespace System.Collections.Generic +{ + public static class CollectionExtensions + { + public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key) + { + TValue value; + dictionary.TryGetValue(key, out value); + return value; + } + + public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key, TValue defaultValue) + { + if (dictionary.ContainsKey(key)) + return dictionary[key]; + return defaultValue; + } + + public static TValue GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key) + { + TValue value; + dictionary.TryGetValue(key, out value); + return value; + } + + public static TValue GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key, TValue defaultValue) + { + if (dictionary.ContainsKey(key)) + return dictionary[key]; + return defaultValue; + } + } +} diff --git a/src/System.Collections/src/System/Collections/Generic/Dictionary.cs b/src/System.Collections/src/System/Collections/Generic/Dictionary.cs index 09d213b2a760..fb00f9fe7d08 100644 --- a/src/System.Collections/src/System/Collections/Generic/Dictionary.cs +++ b/src/System.Collections/src/System/Collections/Generic/Dictionary.cs @@ -537,11 +537,11 @@ public bool TryGetValue(TKey key, out TValue value) return false; } - // This is a convenience method for the internal callers that were converted from using Hashtable. + // This is a convenience method that were converted from using Hashtable. // Many were combining key doesn't exist and key exists but null value (for non-value types) checks. // This allows them to continue getting that behavior with minimal code delta. This is basically // TryGetValue without the out param - internal TValue GetValueOrDefault(TKey key) + public TValue GetValueOrDefault(TKey key) { int i = FindEntry(key); if (i >= 0) @@ -551,6 +551,20 @@ internal TValue GetValueOrDefault(TKey key) return default(TValue); } + // This is a convenience method that were converted from using Hashtable. + // Many were combining key doesn't exist and key exists but null value (for non-value types) checks. + // This allows them to continue getting that behavior with minimal code delta. This is basically + // TryGetValue without the out param + public TValue GetValueOrDefault(TKey key, TValue defaultValue) + { + int i = FindEntry(key); + if (i >= 0) + { + return entries[i].value; + } + return defaultValue; + } + bool ICollection>.IsReadOnly { get { return false; } From f6c5e2fa25403c99f29cc3341b7e0bdc3f33a354 Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Thu, 15 Dec 2016 03:38:53 +0700 Subject: [PATCH 2/6] ArgumentNullException --- .../Generic/CollectionExtensions.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs index 863d003c7264..8f2d80016959 100644 --- a/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs +++ b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs @@ -4,6 +4,11 @@ public static class CollectionExtensions { public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key) { + if (dictionary == null) + { + throw new ArgumentNullException(nameof(dictionary)); + } + TValue value; dictionary.TryGetValue(key, out value); return value; @@ -11,6 +16,11 @@ public static TValue GetValueOrDefault(this IDictionary(this IDictionary dictionary, TKey key, TValue defaultValue) { + if (dictionary == null) + { + throw new ArgumentNullException(nameof(dictionary)); + } + if (dictionary.ContainsKey(key)) return dictionary[key]; return defaultValue; @@ -18,6 +28,11 @@ public static TValue GetValueOrDefault(this IDictionary(this IReadOnlyDictionary dictionary, TKey key) { + if (dictionary == null) + { + throw new ArgumentNullException(nameof(dictionary)); + } + TValue value; dictionary.TryGetValue(key, out value); return value; @@ -25,6 +40,11 @@ public static TValue GetValueOrDefault(this IReadOnlyDictionary(this IReadOnlyDictionary dictionary, TKey key, TValue defaultValue) { + if (dictionary == null) + { + throw new ArgumentNullException(nameof(dictionary)); + } + if (dictionary.ContainsKey(key)) return dictionary[key]; return defaultValue; From 4ba9a68afe20d5406a9b16b4b557d5f8e02312da Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Thu, 15 Dec 2016 04:05:46 +0700 Subject: [PATCH 3/6] Fixed IDictionary.TryGetValue --- .../System/Collections/Generic/CollectionExtensions.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs index 8f2d80016959..dcd413d87e73 100644 --- a/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs +++ b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs @@ -21,8 +21,9 @@ public static TValue GetValueOrDefault(this IDictionary(this IReadOnlyDictionary Date: Thu, 15 Dec 2016 21:16:23 +0700 Subject: [PATCH 4/6] exposed to the contracts --- src/System.Collections/ref/System.Collections.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/System.Collections/ref/System.Collections.cs b/src/System.Collections/ref/System.Collections.cs index 3a68a37e4f7f..56ef35c4bbf8 100644 --- a/src/System.Collections/ref/System.Collections.cs +++ b/src/System.Collections/ref/System.Collections.cs @@ -40,6 +40,15 @@ public static partial class StructuralComparisons } namespace System.Collections.Generic { +#if netcoreapp11 + public static class CollectionExtensions + { + public static TValue GetValueOrDefault(System.Collections.Generic.IDictionary dictionary, TKey key) { throw null; } + public static TValue GetValueOrDefault(System.Collections.Generic.IDictionary dictionary, TKey key, TValue defaultValue) { throw null; } + public static TValue GetValueOrDefault(System.Collections.Generic.IReadOnlyDictionary dictionary, TKey key) { throw null; } + public static TValue GetValueOrDefault(System.Collections.Generic.IReadOnlyDictionary dictionary, TKey key, TValue defaultValue) { throw null; } + } +#endif public abstract partial class Comparer : System.Collections.Generic.IComparer, System.Collections.IComparer { protected Comparer() { } @@ -80,6 +89,10 @@ public void Clear() { } public bool ContainsValue(TValue value) { throw null; } public System.Collections.Generic.Dictionary.Enumerator GetEnumerator() { throw null; } public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } +#if netcoreapp11 + public TValue GetValueOrDefault(TKey key) { throw null; } + public TValue GetValueOrDefault(TKey key, TValue defaultValue) { throw null; } +#endif public virtual void OnDeserialization(object sender) { } public bool Remove(TKey key) { throw null; } void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair keyValuePair) { } From 56091844ebe08635fe4de171347f9701397dc480 Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Mon, 19 Dec 2016 20:47:35 +0700 Subject: [PATCH 5/6] Code review --- .../Generic/CollectionExtensions.cs | 30 +++++-------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs index dcd413d87e73..0d19f9d3ed35 100644 --- a/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs +++ b/src/System.Collections/src/System/Collections/Generic/CollectionExtensions.cs @@ -2,18 +2,11 @@ { public static class CollectionExtensions { - public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key) - { - if (dictionary == null) - { - throw new ArgumentNullException(nameof(dictionary)); - } - - TValue value; - dictionary.TryGetValue(key, out value); - return value; - } + // Method similar to TryGetValue that returns the value instead of putting it in an out param. + public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key) => dictionary.GetValueOrDefault(key, default(TValue)); + // Method similar to TryGetValue that returns the value instead of putting it in an out param. If the entry + // doesn't exist, returns the defaultValue instead. public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key, TValue defaultValue) { if (dictionary == null) @@ -27,18 +20,11 @@ public static TValue GetValueOrDefault(this IDictionary(this IReadOnlyDictionary dictionary, TKey key) - { - if (dictionary == null) - { - throw new ArgumentNullException(nameof(dictionary)); - } - - TValue value; - dictionary.TryGetValue(key, out value); - return value; - } + // Method similar to TryGetValue that returns the value instead of putting it in an out param. + public static TValue GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key) => dictionary.GetValueOrDefault(key, default(TValue)); + // Method similar to TryGetValue that returns the value instead of putting it in an out param. If the entry + // doesn't exist, returns the defaultValue instead. public static TValue GetValueOrDefault(this IReadOnlyDictionary dictionary, TKey key, TValue defaultValue) { if (dictionary == null) From ca342cf1a83308f70352e1661190bbb5c31bdb77 Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Mon, 19 Dec 2016 20:52:37 +0700 Subject: [PATCH 6/6] Code review --- .../System/Collections/Generic/Dictionary.cs | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/System.Collections/src/System/Collections/Generic/Dictionary.cs b/src/System.Collections/src/System/Collections/Generic/Dictionary.cs index fb00f9fe7d08..c3ba8f258b45 100644 --- a/src/System.Collections/src/System/Collections/Generic/Dictionary.cs +++ b/src/System.Collections/src/System/Collections/Generic/Dictionary.cs @@ -537,24 +537,11 @@ public bool TryGetValue(TKey key, out TValue value) return false; } - // This is a convenience method that were converted from using Hashtable. - // Many were combining key doesn't exist and key exists but null value (for non-value types) checks. - // This allows them to continue getting that behavior with minimal code delta. This is basically - // TryGetValue without the out param - public TValue GetValueOrDefault(TKey key) - { - int i = FindEntry(key); - if (i >= 0) - { - return entries[i].value; - } - return default(TValue); - } + // Method similar to TryGetValue that returns the value instead of putting it in an out param. + public TValue GetValueOrDefault(TKey key) => GetValueOrDefault(key, default(TValue)); - // This is a convenience method that were converted from using Hashtable. - // Many were combining key doesn't exist and key exists but null value (for non-value types) checks. - // This allows them to continue getting that behavior with minimal code delta. This is basically - // TryGetValue without the out param + // Method similar to TryGetValue that returns the value instead of putting it in an out param. If the entry + // doesn't exist, returns the defaultValue instead. public TValue GetValueOrDefault(TKey key, TValue defaultValue) { int i = FindEntry(key);