diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs index 798b3d08c9453..aee3d13b9aa0c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs @@ -54,7 +54,7 @@ public Dictionary(int capacity, IEqualityComparer? comparer) Initialize(capacity); } - if (comparer != null && comparer != EqualityComparer.Default) // first check for null to avoid forcing default comparer instantiation unnecessarily + if (comparer is not null && comparer != EqualityComparer.Default) // first check for null to avoid forcing default comparer instantiation unnecessarily { _comparer = comparer; } @@ -62,20 +62,12 @@ public Dictionary(int capacity, IEqualityComparer? comparer) // Special-case EqualityComparer.Default, StringComparer.Ordinal, and StringComparer.OrdinalIgnoreCase. // We use a non-randomized comparer for improved perf, falling back to a randomized comparer if the // hash buckets become unbalanced. - if (typeof(TKey) == typeof(string)) { - if (_comparer is null) - { - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundDefaultComparer; - } - else if (ReferenceEquals(_comparer, StringComparer.Ordinal)) - { - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinal; - } - else if (ReferenceEquals(_comparer, StringComparer.OrdinalIgnoreCase)) + IEqualityComparer? stringComparer = NonRandomizedStringEqualityComparer.GetStringComparer(_comparer); + if (stringComparer is not null) { - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinalIgnoreCase; + _comparer = (IEqualityComparer?)stringComparer; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs index d3516d66aca91..bda3510446545 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/HashSet.cs @@ -54,7 +54,7 @@ public HashSet() : this((IEqualityComparer?)null) { } public HashSet(IEqualityComparer? comparer) { - if (comparer != null && comparer != EqualityComparer.Default) // first check for null to avoid forcing default comparer instantiation unnecessarily + if (comparer is not null && comparer != EqualityComparer.Default) // first check for null to avoid forcing default comparer instantiation unnecessarily { _comparer = comparer; } @@ -62,20 +62,12 @@ public HashSet(IEqualityComparer? comparer) // Special-case EqualityComparer.Default, StringComparer.Ordinal, and StringComparer.OrdinalIgnoreCase. // We use a non-randomized comparer for improved perf, falling back to a randomized comparer if the // hash buckets become unbalanced. - if (typeof(T) == typeof(string)) { - if (_comparer is null) - { - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundDefaultComparer; - } - else if (ReferenceEquals(_comparer, StringComparer.Ordinal)) - { - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinal; - } - else if (ReferenceEquals(_comparer, StringComparer.OrdinalIgnoreCase)) + IEqualityComparer? stringComparer = NonRandomizedStringEqualityComparer.GetStringComparer(_comparer); + if (stringComparer is not null) { - _comparer = (IEqualityComparer)NonRandomizedStringEqualityComparer.WrappedAroundStringComparerOrdinalIgnoreCase; + _comparer = (IEqualityComparer?)stringComparer; } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs index 0ec1a501d56f7..1724cdcd1daf2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs @@ -2,9 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Globalization; using System.Runtime.Serialization; -using Internal.Runtime.CompilerServices; namespace System.Collections.Generic { @@ -20,9 +18,9 @@ public class NonRandomizedStringEqualityComparer : IEqualityComparer, I // that was passed in to the ctor. The caller chooses one of these singletons so that the // GetUnderlyingEqualityComparer method can return the correct value. - internal static readonly NonRandomizedStringEqualityComparer WrappedAroundDefaultComparer = new OrdinalComparer(EqualityComparer.Default); - internal static readonly NonRandomizedStringEqualityComparer WrappedAroundStringComparerOrdinal = new OrdinalComparer(StringComparer.Ordinal); - internal static readonly NonRandomizedStringEqualityComparer WrappedAroundStringComparerOrdinalIgnoreCase = new OrdinalIgnoreCaseComparer(StringComparer.OrdinalIgnoreCase); + private static readonly NonRandomizedStringEqualityComparer WrappedAroundDefaultComparer = new OrdinalComparer(EqualityComparer.Default); + private static readonly NonRandomizedStringEqualityComparer WrappedAroundStringComparerOrdinal = new OrdinalComparer(StringComparer.Ordinal); + private static readonly NonRandomizedStringEqualityComparer WrappedAroundStringComparerOrdinalIgnoreCase = new OrdinalIgnoreCaseComparer(StringComparer.OrdinalIgnoreCase); private readonly IEqualityComparer _underlyingComparer; @@ -109,5 +107,26 @@ internal override RandomizedStringEqualityComparer GetRandomizedEqualityComparer return RandomizedStringEqualityComparer.Create(_underlyingComparer, ignoreCase: true); } } + + public static IEqualityComparer? GetStringComparer(object? comparer) + { + // Special-case EqualityComparer.Default, StringComparer.Ordinal, and StringComparer.OrdinalIgnoreCase. + // We use a non-randomized comparer for improved perf, falling back to a randomized comparer if the + // hash buckets become unbalanced. + if (comparer is null) + { + return WrappedAroundDefaultComparer; + } + else if (ReferenceEquals(comparer, StringComparer.Ordinal)) + { + return WrappedAroundStringComparerOrdinal; + } + else if (ReferenceEquals(comparer, StringComparer.OrdinalIgnoreCase)) + { + return WrappedAroundStringComparerOrdinalIgnoreCase; + } + + return null; + } } }