From dfb92670cd667ac51f2abc024a06b5b52b0fa484 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 30 Dec 2018 01:30:48 -0800 Subject: [PATCH] Fix CoreRT build breaks --- .../System/Collections/Generic/Comparer.cs | 10 +- .../Collections/Generic/EqualityComparer.cs | 14 +- .../shared/System/ThrowHelper.cs | 3 + .../IntrinsicSupport/ComparerHelpers.cs | 108 ------------- .../EqualityComparerHelpers.cs | 152 +----------------- .../src/System.Private.CoreLib.csproj | 5 +- .../Collections/Generic/Comparer.CoreRT.cs | 53 ++++++ .../System/Collections/Generic/Comparer.cs | 129 --------------- .../Generic/CompatibilityEqualityComparers.cs | 52 ------ .../Generic/EqualityComparer.CoreRT.cs | 54 +++++++ .../Collections/Generic/EqualityComparer.cs | 118 -------------- 11 files changed, 123 insertions(+), 575 deletions(-) create mode 100644 src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreRT.cs delete mode 100644 src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs delete mode 100644 src/System.Private.CoreLib/src/System/Collections/Generic/CompatibilityEqualityComparers.cs create mode 100644 src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.CoreRT.cs delete mode 100644 src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/Comparer.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/Comparer.cs index f60d0c5f6f7..f7c6cf81dd6 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/Comparer.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/Comparer.cs @@ -2,15 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - -using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System.Collections.Generic { [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract partial class Comparer : IComparer, IComparer { // public static Comparer Default is runtime-specific @@ -56,7 +54,7 @@ public override int Compare(T x, T y) // means another generic instantiation, which can be costly esp. // for value types. [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class GenericComparer : Comparer where T : IComparable { @@ -80,7 +78,7 @@ public override int GetHashCode() => } [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class NullableComparer : Comparer where T : struct, IComparable { @@ -104,7 +102,7 @@ public override int GetHashCode() => } [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class ObjectComparer : Comparer { diff --git a/src/System.Private.CoreLib/shared/System/Collections/Generic/EqualityComparer.cs b/src/System.Private.CoreLib/shared/System/Collections/Generic/EqualityComparer.cs index c04f1219980..01204775e92 100644 --- a/src/System.Private.CoreLib/shared/System/Collections/Generic/EqualityComparer.cs +++ b/src/System.Private.CoreLib/shared/System/Collections/Generic/EqualityComparer.cs @@ -2,15 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.Serialization; -using System.Diagnostics; namespace System.Collections.Generic { [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public abstract partial class EqualityComparer : IEqualityComparer, IEqualityComparer { // public static EqualityComparer Default is runtime-specific @@ -39,7 +37,7 @@ bool IEqualityComparer.Equals(object x, object y) // The methods in this class look identical to the inherited methods, but the calls // to Equal bind to IEquatable.Equals(T) instead of Object.Equals(Object) [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class GenericEqualityComparer : EqualityComparer where T : IEquatable { @@ -69,7 +67,7 @@ public override int GetHashCode() => } [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class NullableEqualityComparer : EqualityComparer where T : struct, IEquatable { @@ -97,7 +95,7 @@ public override int GetHashCode() => } [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class ObjectEqualityComparer : EqualityComparer { @@ -125,7 +123,7 @@ public override int GetHashCode() => } [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class ByteEqualityComparer : EqualityComparer { @@ -150,7 +148,7 @@ public override int GetHashCode() => } [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] // Needs to be public to support binary serialization compatibility public sealed partial class EnumEqualityComparer : EqualityComparer, ISerializable where T : struct, Enum { diff --git a/src/System.Private.CoreLib/shared/System/ThrowHelper.cs b/src/System.Private.CoreLib/shared/System/ThrowHelper.cs index 09b2f0af2b7..0c80cd3cd8e 100644 --- a/src/System.Private.CoreLib/shared/System/ThrowHelper.cs +++ b/src/System.Private.CoreLib/shared/System/ThrowHelper.cs @@ -414,6 +414,8 @@ private static string GetResourceString(ExceptionResource resource) { switch (resource) { + case ExceptionResource.Argument_InvalidArgumentForComparison: + return SR.Argument_InvalidArgumentForComparison; case ExceptionResource.ArgumentOutOfRange_Index: return SR.ArgumentOutOfRange_Index; case ExceptionResource.ArgumentOutOfRange_Count: @@ -572,6 +574,7 @@ internal enum ExceptionArgument // internal enum ExceptionResource { + Argument_InvalidArgumentForComparison, ArgumentOutOfRange_Index, ArgumentOutOfRange_Count, Arg_ArrayPlusOffTooSmall, diff --git a/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs b/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs index f8822391707..dd80cce8a0d 100644 --- a/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs +++ b/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/ComparerHelpers.cs @@ -13,7 +13,6 @@ using System.Collections.Generic; using System.Runtime; -using Internal.IntrinsicSupport; using Internal.Runtime.Augments; namespace Internal.IntrinsicSupport @@ -113,112 +112,5 @@ private static Comparer GetKnownObjectComparer() { return new ObjectComparer(); } - - // This routine emulates System.Collection.Comparer.Default.Compare(), which lives in the System.Collections.NonGenerics contract. - // To avoid adding a reference to that contract just for this hack, we'll replicate the implementation here. - internal static int CompareObjects(object x, object y) - { - if (x == y) - return 0; - - if (x == null) - return -1; - - if (y == null) - return 1; - - { - // System.Collection.Comparer.Default.Compare() compares strings using the CurrentCulture. - string sx = x as string; - string sy = y as string; - if (sx != null && sy != null) - return string.Compare(sx, sy, StringComparison.CurrentCulture); - } - - IComparable ix = x as IComparable; - if (ix != null) - return ix.CompareTo(y); - - IComparable iy = y as IComparable; - if (iy != null) - return -iy.CompareTo(x); - - throw new ArgumentException(SR.Argument_ImplementIComparable); - } - } -} - -namespace System.Collections.Generic -{ - //----------------------------------------------------------------------- - // Implementations of EqualityComparer for the various possible scenarios - // Because these are serializable, they must not be renamed - //----------------------------------------------------------------------- - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class GenericComparer : Comparer where T : IComparable - { - public sealed override int Compare(T x, T y) - { - if (x != null) - { - if (y != null) - return x.CompareTo(y); - - return 1; - } - - if (y != null) - return -1; - - return 0; - } - - // Equals method for the comparer itself. - public sealed override bool Equals(object obj) => obj != null && GetType() == obj.GetType(); - - public sealed override int GetHashCode() => GetType().GetHashCode(); - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class NullableComparer : Comparer> where T : struct, IComparable - { - public sealed override int Compare(Nullable x, Nullable y) - { - if (x.HasValue) - { - if (y.HasValue) - return x.Value.CompareTo(y.Value); - - return 1; - } - - if (y.HasValue) - return -1; - - return 0; - } - - // Equals method for the comparer itself. - public sealed override bool Equals(object obj) => obj != null && GetType() == obj.GetType(); - - public sealed override int GetHashCode() => GetType().GetHashCode(); - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class ObjectComparer : Comparer - { - public sealed override int Compare(T x, T y) - { - return ComparerHelpers.CompareObjects(x, y); - } - - // Equals method for the comparer itself. - public sealed override bool Equals(object obj) => obj != null && GetType() == obj.GetType(); - - public sealed override int GetHashCode() => GetType().GetHashCode(); } } - diff --git a/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs b/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs index b9c735ca1ea..c11615aad21 100644 --- a/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs +++ b/src/System.Private.CoreLib/src/Internal/IntrinsicSupport/EqualityComparerHelpers.cs @@ -16,8 +16,6 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; -using System.Runtime.Serialization; -using Internal.IntrinsicSupport; using Internal.Runtime.Augments; namespace Internal.IntrinsicSupport @@ -127,7 +125,7 @@ private static EqualityComparer GetKnownObjectEquatableComparer() return new ObjectEqualityComparer(); } - private static EqualityComparer GetKnownEnumEquatableComparer() where T : struct + private static EqualityComparer GetKnownEnumEquatableComparer() where T : struct, Enum { return new EnumEqualityComparer(); } @@ -207,151 +205,3 @@ internal static bool StructOnlyEquals(T left, T right) } } } - -namespace System.Collections.Generic -{ - //----------------------------------------------------------------------- - // Implementations of EqualityComparer for the various possible scenarios - // Names must match other runtimes for serialization - //----------------------------------------------------------------------- - - // The methods in this class look identical to the inherited methods, but the calls - // to Equal bind to IEquatable.Equals(T) instead of Object.Equals(Object) - [Serializable] - public sealed class GenericEqualityComparer : EqualityComparer where T : IEquatable - { - public sealed override bool Equals(T x, T y) - { - if (x != null) - { - if (y != null) - return x.Equals(y); - return false; - } - - if (y != null) - return false; - - return true; - } - - public sealed override int GetHashCode(T obj) - { - if (obj == null) - return 0; - - return obj.GetHashCode(); - } - - // Equals method for the comparer itself. - public sealed override bool Equals(object obj) => obj is GenericEqualityComparer; - - public sealed override int GetHashCode() => typeof(GenericEqualityComparer).GetHashCode(); - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class NullableEqualityComparer : EqualityComparer> where T : struct, IEquatable - { - public sealed override bool Equals(Nullable x, Nullable y) - { - if (x.HasValue) - { - if (y.HasValue) - return x.Value.Equals(y.Value); - return false; - } - - if (y.HasValue) - return false; - - return true; - } - - public sealed override int GetHashCode(Nullable obj) - { - return obj.GetHashCode(); - } - - - // Equals method for the comparer itself. - public sealed override bool Equals(object obj) => obj is NullableEqualityComparer; - - public sealed override int GetHashCode() => typeof(NullableEqualityComparer).GetHashCode(); - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public class EnumEqualityComparer : EqualityComparer, ISerializable where T : struct - { - public sealed override bool Equals(T x, T y) - { - return EqualityComparerHelpers.EnumOnlyEquals(x, y); - } - - public sealed override int GetHashCode(T obj) - { - return obj.GetHashCode(); - } - - internal EnumEqualityComparer() { } - - private EnumEqualityComparer(SerializationInfo info, StreamingContext context) { } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - // For back-compat we need to serialize the comparers for enums with underlying types other than int as ObjectEqualityComparer - if (Type.GetTypeCode(Enum.GetUnderlyingType(typeof(T))) != TypeCode.Int32) - { - info.SetType(typeof(ObjectEqualityComparer)); - } - } - - // Equals method for the comparer itself. - public override bool Equals(object obj) => obj is EnumEqualityComparer; - - public override int GetHashCode() => typeof(EnumEqualityComparer).GetHashCode(); - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class ObjectEqualityComparer : EqualityComparer - { - public sealed override bool Equals(T x, T y) - { - if (x != null) - { - if (y != null) - return x.Equals(y); - return false; - } - - if (y != null) - return false; - - return true; - } - - public sealed override int GetHashCode(T obj) - { - if (obj == null) - return 0; - return obj.GetHashCode(); - } - - // Equals method for the comparer itself. - public sealed override bool Equals(object obj) - { - if(obj == null) - { - return false; - } - - // This needs to use GetType instead of typeof to avoid infinite recursion in the type loader - return obj.GetType().Equals(GetType()); - } - - // This needs to use GetType instead of typeof to avoid infinite recursion in the type loader - public sealed override int GetHashCode() => GetType().GetHashCode(); - } -} diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 0b8cc7848fb..534b8686939 100644 --- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -194,9 +194,8 @@ - - - + + diff --git a/src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreRT.cs b/src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreRT.cs new file mode 100644 index 00000000000..47385560ee2 --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.CoreRT.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +using Internal.IntrinsicSupport; + +namespace System.Collections.Generic +{ + public abstract partial class Comparer : IComparer, IComparer + { + // WARNING: We allow diagnostic tools to directly inspect this member (_default). + // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details. + // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools. + // Get in touch with the diagnostics team if you have questions. + private static Comparer _default; + + [Intrinsic] + private static Comparer Create() + { +#if PROJECTN + // The compiler will overwrite the Create method with optimized + // instantiation-specific implementation. + _default = null; + throw new NotSupportedException(); +#else + // The compiler will overwrite the Create method with optimized + // instantiation-specific implementation. + // This body serves as a fallback when instantiation-specific implementation is unavailable. + return (_default = ComparerHelpers.GetUnknownComparer()); +#endif + } + + public static Comparer Default + { + get + { + // Lazy initialization produces smaller code for CoreRT than initialization in constructor + return _default ?? Create(); + } + } + } + + internal sealed partial class EnumComparer : Comparer where T : struct, Enum + { + public override int Compare(T x, T y) + { + // CORERT-TODO: EnumComparer + throw new NotImplementedException(); + } + } +} diff --git a/src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs b/src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs deleted file mode 100644 index 4bb79e4612e..00000000000 --- a/src/System.Private.CoreLib/src/System/Collections/Generic/Comparer.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.CompilerServices; - -using Internal.IntrinsicSupport; - -namespace System.Collections.Generic -{ - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public abstract class Comparer : IComparer, IComparer - { - // WARNING: We allow diagnostic tools to directly inspect this member (_default). - // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details. - // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools. - // Get in touch with the diagnostics team if you have questions. - private static Comparer _default; - - [Intrinsic] - private static Comparer Create() - { -#if PROJECTN - // The compiler will overwrite the Create method with optimized - // instantiation-specific implementation. - _default = null; - throw new NotSupportedException(); -#else - // The compiler will overwrite the Create method with optimized - // instantiation-specific implementation. - // This body serves as a fallback when instantiation-specific implementation is unavailable. - return (_default = ComparerHelpers.GetUnknownComparer()); -#endif - } - - protected Comparer() - { - } - - public static Comparer Default - { - get - { - // Lazy initialization produces smaller code for CoreRT than initialization in constructor - return _default ?? Create(); - } - } - - public abstract int Compare(T x, T y); - - public static Comparer Create(Comparison comparison) - { - if (comparison == null) - throw new ArgumentNullException(nameof(comparison)); - - return new ComparisonComparer(comparison); - } - - int System.Collections.IComparer.Compare(object x, object y) - { - if (x == null) return y == null ? 0 : -1; - if (y == null) return 1; - if (x is T && y is T) return Compare((T)x, (T)y); - throw new ArgumentException(SR.Argument_InvalidArgumentForComparison); - } - } - -#if false - internal class DefaultComparer : Comparer - { - public override int Compare(T x, T y) - { - // Desktop compat note: If either x or y are null, this api must not invoke either IComparable.Compare or IComparable.Compare on either - // x or y. - if (x == null) - { - if (y == null) - return 0; - else - return -1; - } - if (y == null) - return 1; - - IComparable igcx = x as IComparable; - if (igcx != null) - return igcx.CompareTo(y); - IComparable igcy = y as IComparable; - if (igcy != null) - return -igcy.CompareTo(x); - - return CompareUsingIComparable(x, y); - } - - private int CompareUsingIComparable(object a, object b) - { - if (a == b) return 0; - if (a == null) return -1; - if (b == null) return 1; - - IComparable ia = a as IComparable; - if (ia != null) - return ia.CompareTo(b); - - IComparable ib = b as IComparable; - if (ib != null) - return -ib.CompareTo(a); - - throw new ArgumentException(SR.Argument_ImplementIComparable); - } - } -#endif - - internal class ComparisonComparer : Comparer - { - private readonly Comparison _comparison; - - public ComparisonComparer(Comparison comparison) - { - _comparison = comparison; - } - - public override int Compare(T x, T y) - { - return _comparison(x, y); - } - } -} diff --git a/src/System.Private.CoreLib/src/System/Collections/Generic/CompatibilityEqualityComparers.cs b/src/System.Private.CoreLib/src/System/Collections/Generic/CompatibilityEqualityComparers.cs deleted file mode 100644 index c22edd601be..00000000000 --- a/src/System.Private.CoreLib/src/System/Collections/Generic/CompatibilityEqualityComparers.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Runtime.Serialization; - -namespace System.Collections.Generic -{ - // Comparers that exist for serialization compatibility with .NET Framework - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class ByteEqualityComparer : EqualityComparer - { - public override bool Equals(byte x, byte y) - { - return x == y; - } - - public override int GetHashCode(byte obj) - { - return obj.GetHashCode(); - } - - // Equals method for the comparer itself. - public override bool Equals(object obj) => obj != null && GetType() == obj.GetType(); - - public override int GetHashCode() => GetType().GetHashCode(); - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class SByteEnumEqualityComparer : EnumEqualityComparer where T : struct - { - private SByteEnumEqualityComparer(SerializationInfo information, StreamingContext context) { } - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class ShortEnumEqualityComparer : EnumEqualityComparer where T : struct - { - private ShortEnumEqualityComparer(SerializationInfo information, StreamingContext context) { } - } - - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public sealed class LongEnumEqualityComparer : EnumEqualityComparer where T : struct - { - private LongEnumEqualityComparer(SerializationInfo information, StreamingContext context) { } - } -} diff --git a/src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.CoreRT.cs b/src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.CoreRT.cs new file mode 100644 index 00000000000..9c5221415bb --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.CoreRT.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +using System.Runtime.CompilerServices; + +using Internal.IntrinsicSupport; + +namespace System.Collections.Generic +{ + public abstract partial class EqualityComparer : IEqualityComparer, IEqualityComparer + { + // WARNING: We allow diagnostic tools to directly inspect this member (_default). + // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details. + // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools. + // Get in touch with the diagnostics team if you have questions. + private static EqualityComparer _default; + + [Intrinsic] + private static EqualityComparer Create() + { +#if PROJECTN + // The compiler will overwrite the Create method with optimized + // instantiation-specific implementation. + _default = null; + throw new NotSupportedException(); +#else + // The compiler will overwrite the Create method with optimized + // instantiation-specific implementation. + // This body serves as a fallback when instantiation-specific implementation is unavailable. + return (_default = EqualityComparerHelpers.GetUnknownEquatableComparer()); +#endif + } + + public static EqualityComparer Default + { + [Intrinsic] + get + { + // Lazy initialization produces smaller code for CoreRT than initialization in constructor + return _default ?? Create(); + } + } + } + + public sealed partial class EnumEqualityComparer : EqualityComparer where T : struct, Enum + { + public sealed override bool Equals(T x, T y) + { + return EqualityComparerHelpers.EnumOnlyEquals(x, y); + } + } +} diff --git a/src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs b/src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs deleted file mode 100644 index 691f7d91483..00000000000 --- a/src/System.Private.CoreLib/src/System/Collections/Generic/EqualityComparer.cs +++ /dev/null @@ -1,118 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - - -using System.Runtime.CompilerServices; - -using Internal.IntrinsicSupport; - -namespace System.Collections.Generic -{ - [Serializable] - [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] - public abstract class EqualityComparer : IEqualityComparer, IEqualityComparer - { - // WARNING: We allow diagnostic tools to directly inspect this member (_default). - // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details. - // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools. - // Get in touch with the diagnostics team if you have questions. - private static EqualityComparer _default; - - [Intrinsic] - private static EqualityComparer Create() - { -#if PROJECTN - // The compiler will overwrite the Create method with optimized - // instantiation-specific implementation. - _default = null; - throw new NotSupportedException(); -#else - // The compiler will overwrite the Create method with optimized - // instantiation-specific implementation. - // This body serves as a fallback when instantiation-specific implementation is unavailable. - return (_default = EqualityComparerHelpers.GetUnknownEquatableComparer()); -#endif - } - - protected EqualityComparer() - { - } - - public static EqualityComparer Default - { - [Intrinsic] - get - { - // Lazy initialization produces smaller code for CoreRT than initialization in constructor - return _default ?? Create(); - } - } - - public abstract bool Equals(T x, T y); - - public abstract int GetHashCode(T obj); - - int IEqualityComparer.GetHashCode(object obj) - { - if (obj == null) - return 0; - if (obj is T) - return GetHashCode((T)obj); - throw new ArgumentException(SR.Argument_InvalidArgumentForComparison, nameof(obj)); - } - - bool IEqualityComparer.Equals(object x, object y) - { - if (x == y) - return true; - if (x == null || y == null) - return false; - if ((x is T) && (y is T)) - return Equals((T)x, (T)y); - throw new ArgumentException(SR.Argument_InvalidArgumentForComparison); - } - } - -#if false - internal sealed class DefaultEqualityComparer : EqualityComparer - { - public DefaultEqualityComparer() - { - } - - public sealed override bool Equals(T x, T y) - { - if (x == null) - return y == null; - if (y == null) - return false; - - return x.Equals(y); - } - - public sealed override int GetHashCode(T obj) - { - if (obj == null) - return 0; - return obj.GetHashCode(); - } - - // Equals method for the comparer itself. - public sealed override bool Equals(Object obj) - { - if (obj == null) - { - return false; - } - - // This needs to use GetType instead of typeof to avoid infinite recursion in the type loader - return obj.GetType().Equals(GetType()); - } - - - // This needs to use GetType instead of typeof to avoid infinite recursion in the type loader - public sealed override int GetHashCode() => GetType().GetHashCode(); - } -#endif -}