<Compile Include="$(BclSourcesRoot)\System\CLRConfig.cs" />
<Compile Include="$(BclSourcesRoot)\System\Collections\EmptyReadOnlyDictionaryInternal.cs" />
<Compile Include="$(BclSourcesRoot)\System\Collections\Generic\ArraySortHelper.CoreCLR.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\Comparer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\Comparer.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Collections\Generic\ComparerHelpers.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\EqualityComparer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\EqualityComparer.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Collections\ObjectModel\ReadOnlyDictionary.cs" />
<Compile Include="$(BclSourcesRoot)\System\Currency.cs" />
<Compile Include="$(BclSourcesRoot)\System\DefaultBinder.CanConvert.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Concurrent\IProducerConsumerCollectionDebugView.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\DictionaryEntry.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\ArraySortHelper.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\Comparer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\Dictionary.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\EqualityComparer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IAsyncEnumerable.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IAsyncEnumerator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\ICollection.cs" />
namespace System.Collections.Generic
{
[Serializable]
- [TypeDependencyAttribute("System.Collections.Generic.ObjectComparer`1")]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- public abstract class Comparer<T> : IComparer, IComparer<T>
+ public abstract partial class Comparer<T> : IComparer, IComparer<T>
{
- // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
- // as possible and define most of the creation logic in a non-generic class.
- public static Comparer<T> Default { get; } = (Comparer<T>)ComparerHelpers.CreateDefaultComparer(typeof(T));
+ // public static Comparer<T> Default is runtime-specific
public static Comparer<T> Create(Comparison<T> comparison)
{
}
}
+ internal sealed class ComparisonComparer<T> : Comparer<T>
+ {
+ private readonly Comparison<T> _comparison;
+
+ public ComparisonComparer(Comparison<T> comparison)
+ {
+ _comparison = comparison;
+ }
+
+ public override int Compare(T x, T y)
+ {
+ return _comparison(x, y);
+ }
+ }
+
// Note: although there is a lot of shared code in the following
// comparers, we do not incorporate it into a base class for perf
// reasons. Adding another base class (even one with no fields)
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
// Needs to be public to support binary serialization compatibility
- public sealed class GenericComparer<T> : Comparer<T> where T : IComparable<T>
+ public sealed partial class GenericComparer<T> : Comparer<T> where T : IComparable<T>
{
public override int Compare(T x, T y)
{
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
// Needs to be public to support binary serialization compatibility
- public sealed class NullableComparer<T> : Comparer<T?> where T : struct, IComparable<T>
+ public sealed partial class NullableComparer<T> : Comparer<T?> where T : struct, IComparable<T>
{
public override int Compare(T? x, T? y)
{
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
// Needs to be public to support binary serialization compatibility
- public sealed class ObjectComparer<T> : Comparer<T>
+ public sealed partial class ObjectComparer<T> : Comparer<T>
{
public override int Compare(T x, T y)
{
GetType().GetHashCode();
}
- internal sealed class ComparisonComparer<T> : Comparer<T>
- {
- private readonly Comparison<T> _comparison;
-
- public ComparisonComparer(Comparison<T> comparison)
- {
- _comparison = comparison;
- }
-
- public override int Compare(T x, T y)
- {
- return _comparison(x, y);
- }
- }
-
- // Enum comparers (specialized to avoid boxing)
- // NOTE: Each of these needs to implement ISerializable
- // and have a SerializationInfo/StreamingContext ctor,
- // since we want to serialize as ObjectComparer for
- // back-compat reasons (see below).
[Serializable]
- internal sealed class EnumComparer<T> : Comparer<T>, ISerializable where T : struct, Enum
+ internal sealed partial class EnumComparer<T> : Comparer<T>, ISerializable where T : struct, Enum
{
internal EnumComparer() { }
// Used by the serialization engine.
private EnumComparer(SerializationInfo info, StreamingContext context) { }
- public override int Compare(T x, T y)
- {
- return System.Runtime.CompilerServices.JitHelpers.EnumCompareTo(x, y);
- }
+ // public override int Compare(T x, T y) is runtime-specific
// Equals method for the comparer itself.
public override bool Equals(object obj) =>
--- /dev/null
+// 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;
+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")]
+ public abstract partial class EqualityComparer<T> : IEqualityComparer, IEqualityComparer<T>
+ {
+ // public static EqualityComparer<T> Default is runtime-specific
+
+ 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);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison);
+ return 0;
+ }
+
+ 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);
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison);
+ return false;
+ }
+ }
+
+ // The methods in this class look identical to the inherited methods, but the calls
+ // to Equal bind to IEquatable<T>.Equals(T) instead of Object.Equals(Object)
+ [Serializable]
+ [System.Runtime.CompilerServices.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<T> : EqualityComparer<T> where T : IEquatable<T>
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public 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;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
+
+ // Equals method for the comparer itself.
+ // If in the future this type is made sealed, change the is check to obj != null && GetType() == obj.GetType().
+ public override bool Equals(object obj) =>
+ obj is GenericEqualityComparer<T>;
+
+ // If in the future this type is made sealed, change typeof(...) to GetType().
+ public override int GetHashCode() =>
+ typeof(GenericEqualityComparer<T>).GetHashCode();
+ }
+
+ [Serializable]
+ [System.Runtime.CompilerServices.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<T> : EqualityComparer<T?> where T : struct, IEquatable<T>
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override bool Equals(T? x, T? y)
+ {
+ if (x.HasValue)
+ {
+ if (y.HasValue) return x.value.Equals(y.value);
+ return false;
+ }
+ if (y.HasValue) return false;
+ return true;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override int GetHashCode(T? obj) => 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")]
+ // Needs to be public to support binary serialization compatibility
+ public sealed partial class ObjectEqualityComparer<T> : EqualityComparer<T>
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public 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;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
+
+ // 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")]
+ // Needs to be public to support binary serialization compatibility
+ public sealed partial class ByteEqualityComparer : EqualityComparer<byte>
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override bool Equals(byte x, byte y)
+ {
+ return x == y;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override int GetHashCode(byte b)
+ {
+ return b.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")]
+ // Needs to be public to support binary serialization compatibility
+ public sealed partial class EnumEqualityComparer<T> : EqualityComparer<T>, ISerializable where T : struct, Enum
+ {
+ internal EnumEqualityComparer() { }
+
+ // This is used by the serialization engine.
+ private EnumEqualityComparer(SerializationInfo information, 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<T>));
+ }
+ }
+
+ // public override bool Equals(T x, T y) is runtime-specific
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override int GetHashCode(T 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();
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+
+namespace System.Collections.Generic
+{
+ [TypeDependencyAttribute("System.Collections.Generic.ObjectComparer`1")]
+ public abstract partial class Comparer<T> : IComparer, IComparer<T>
+ {
+ // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
+ // as possible and define most of the creation logic in a non-generic class.
+ public static Comparer<T> Default { get; } = (Comparer<T>)ComparerHelpers.CreateDefaultComparer(typeof(T));
+ }
+
+ internal sealed partial class EnumComparer<T> : Comparer<T> where T : struct, Enum
+ {
+ public override int Compare(T x, T y)
+ {
+ return System.Runtime.CompilerServices.JitHelpers.EnumCompareTo(x, y);
+ }
+ }
+}
--- /dev/null
+// 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;
+using System.Runtime.CompilerServices;
+using System.Diagnostics;
+
+namespace System.Collections.Generic
+{
+ [TypeDependencyAttribute("System.Collections.Generic.ObjectEqualityComparer`1")]
+ public abstract partial class EqualityComparer<T> : IEqualityComparer, IEqualityComparer<T>
+ {
+ // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
+ // as possible and define most of the creation logic in a non-generic class.
+ public static EqualityComparer<T> Default { [Intrinsic] get; } = (EqualityComparer<T>)ComparerHelpers.CreateDefaultEqualityComparer(typeof(T));
+
+ internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex + count;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (Equals(array[i], value)) return i;
+ }
+ return -1;
+ }
+
+ internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex - count + 1;
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (Equals(array[i], value)) return i;
+ }
+ return -1;
+ }
+ }
+
+ public sealed partial class GenericEqualityComparer<T> : EqualityComparer<T> where T : IEquatable<T>
+ {
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex + count;
+ if (value == null)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (array[i] == null) return i;
+ }
+ }
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (array[i] != null && array[i].Equals(value)) return i;
+ }
+ }
+ return -1;
+ }
+
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex - count + 1;
+ if (value == null)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (array[i] == null) return i;
+ }
+ }
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (array[i] != null && array[i].Equals(value)) return i;
+ }
+ }
+ return -1;
+ }
+ }
+
+ public sealed partial class NullableEqualityComparer<T> : EqualityComparer<T?> where T : struct, IEquatable<T>
+ {
+ internal override int IndexOf(T?[] array, T? value, int startIndex, int count)
+ {
+ int endIndex = startIndex + count;
+ if (!value.HasValue)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (!array[i].HasValue) return i;
+ }
+ }
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
+ }
+ }
+ return -1;
+ }
+
+ internal override int LastIndexOf(T?[] array, T? value, int startIndex, int count)
+ {
+ int endIndex = startIndex - count + 1;
+ if (!value.HasValue)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (!array[i].HasValue) return i;
+ }
+ }
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
+ }
+ }
+ return -1;
+ }
+ }
+
+ public sealed partial class ObjectEqualityComparer<T> : EqualityComparer<T>
+ {
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex + count;
+ if (value == null)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (array[i] == null) return i;
+ }
+ }
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (array[i] != null && array[i].Equals(value)) return i;
+ }
+ }
+ return -1;
+ }
+
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex - count + 1;
+ if (value == null)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (array[i] == null) return i;
+ }
+ }
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (array[i] != null && array[i].Equals(value)) return i;
+ }
+ }
+ return -1;
+ }
+ }
+
+ public sealed partial class ByteEqualityComparer : EqualityComparer<byte>
+ {
+#if DEBUG
+ internal override int IndexOf(byte[] array, byte value, int startIndex, int count)
+ {
+ Debug.Fail("Should not get here.");
+ return -1;
+ }
+
+ internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count)
+ {
+ Debug.Fail("Should not get here.");
+ return -1;
+ }
+#endif
+ }
+
+ public sealed partial class EnumEqualityComparer<T> : EqualityComparer<T> where T : struct, Enum
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override bool Equals(T x, T y)
+ {
+ return System.Runtime.CompilerServices.JitHelpers.EnumEquals(x, y);
+ }
+
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex + count;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (System.Runtime.CompilerServices.JitHelpers.EnumEquals(array[i], value)) return i;
+ }
+ return -1;
+ }
+
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
+ int endIndex = startIndex - count + 1;
+ for (int i = startIndex; i >= endIndex; i--)
+ {
+ if (System.Runtime.CompilerServices.JitHelpers.EnumEquals(array[i], value)) return i;
+ }
+ return -1;
+ }
+ }
+}
+++ /dev/null
-// 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.Collections;
-using System.Collections.Generic;
-using System.Security;
-
-using System.Globalization;
-using System.Runtime;
-using System.Runtime.CompilerServices;
-using System.Runtime.Serialization;
-using System.Diagnostics;
-
-namespace System.Collections.Generic
-{
- [Serializable]
- [TypeDependencyAttribute("System.Collections.Generic.ObjectEqualityComparer`1")]
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- public abstract class EqualityComparer<T> : IEqualityComparer, IEqualityComparer<T>
- {
- // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
- // as possible and define most of the creation logic in a non-generic class.
- public static EqualityComparer<T> Default { [Intrinsic] get; } = (EqualityComparer<T>)ComparerHelpers.CreateDefaultEqualityComparer(typeof(T));
-
- public abstract bool Equals(T x, T y);
- public abstract int GetHashCode(T obj);
-
- internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex + count;
- for (int i = startIndex; i < endIndex; i++)
- {
- if (Equals(array[i], value)) return i;
- }
- return -1;
- }
-
- internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex - count + 1;
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (Equals(array[i], value)) return i;
- }
- return -1;
- }
-
- int IEqualityComparer.GetHashCode(object obj)
- {
- if (obj == null) return 0;
- if (obj is T) return GetHashCode((T)obj);
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison);
- return 0;
- }
-
- 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);
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison);
- return false;
- }
- }
-
- // The methods in this class look identical to the inherited methods, but the calls
- // to Equal bind to IEquatable<T>.Equals(T) instead of Object.Equals(Object)
- [Serializable]
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- // Needs to be public to support binary serialization compatibility
- public sealed class GenericEqualityComparer<T> : EqualityComparer<T> where T : IEquatable<T>
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public 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;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
-
- internal override int IndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex + count;
- if (value == null)
- {
- for (int i = startIndex; i < endIndex; i++)
- {
- if (array[i] == null) return i;
- }
- }
- else
- {
- for (int i = startIndex; i < endIndex; i++)
- {
- if (array[i] != null && array[i].Equals(value)) return i;
- }
- }
- return -1;
- }
-
- internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex - count + 1;
- if (value == null)
- {
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (array[i] == null) return i;
- }
- }
- else
- {
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (array[i] != null && array[i].Equals(value)) return i;
- }
- }
- return -1;
- }
-
- // Equals method for the comparer itself.
- // If in the future this type is made sealed, change the is check to obj != null && GetType() == obj.GetType().
- public override bool Equals(object obj) =>
- obj is GenericEqualityComparer<T>;
-
- // If in the future this type is made sealed, change typeof(...) to GetType().
- public override int GetHashCode() =>
- typeof(GenericEqualityComparer<T>).GetHashCode();
- }
-
- [Serializable]
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
- // Needs to be public to support binary serialization compatibility
- public sealed class NullableEqualityComparer<T> : EqualityComparer<T?> where T : struct, IEquatable<T>
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override bool Equals(T? x, T? y)
- {
- if (x.HasValue)
- {
- if (y.HasValue) return x.value.Equals(y.value);
- return false;
- }
- if (y.HasValue) return false;
- return true;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override int GetHashCode(T? obj) => obj.GetHashCode();
-
- internal override int IndexOf(T?[] array, T? value, int startIndex, int count)
- {
- int endIndex = startIndex + count;
- if (!value.HasValue)
- {
- for (int i = startIndex; i < endIndex; i++)
- {
- if (!array[i].HasValue) return i;
- }
- }
- else
- {
- for (int i = startIndex; i < endIndex; i++)
- {
- if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
- }
- }
- return -1;
- }
-
- internal override int LastIndexOf(T?[] array, T? value, int startIndex, int count)
- {
- int endIndex = startIndex - count + 1;
- if (!value.HasValue)
- {
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (!array[i].HasValue) return i;
- }
- }
- else
- {
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
- }
- }
- return -1;
- }
-
- // 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")]
- // Needs to be public to support binary serialization compatibility
- public sealed class ObjectEqualityComparer<T> : EqualityComparer<T>
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public 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;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
-
- internal override int IndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex + count;
- if (value == null)
- {
- for (int i = startIndex; i < endIndex; i++)
- {
- if (array[i] == null) return i;
- }
- }
- else
- {
- for (int i = startIndex; i < endIndex; i++)
- {
- if (array[i] != null && array[i].Equals(value)) return i;
- }
- }
- return -1;
- }
-
- internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex - count + 1;
- if (value == null)
- {
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (array[i] == null) return i;
- }
- }
- else
- {
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (array[i] != null && array[i].Equals(value)) return i;
- }
- }
- return -1;
- }
-
- // 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")]
- // Needs to be public to support binary serialization compatibility
- public sealed class ByteEqualityComparer : EqualityComparer<byte>
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override bool Equals(byte x, byte y)
- {
- return x == y;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override int GetHashCode(byte b)
- {
- return b.GetHashCode();
- }
-
-#if DEBUG
- internal override int IndexOf(byte[] array, byte value, int startIndex, int count)
- {
- Debug.Fail("Should not get here.");
- return -1;
- }
-
- internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count)
- {
- Debug.Fail("Should not get here.");
- return -1;
- }
-#endif
-
- // 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")]
- // Needs to be public to support binary serialization compatibility
- public sealed class EnumEqualityComparer<T> : EqualityComparer<T>, ISerializable where T : struct, Enum
- {
- internal EnumEqualityComparer() { }
-
- // This is used by the serialization engine.
- private EnumEqualityComparer(SerializationInfo information, 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<T>));
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override bool Equals(T x, T y)
- {
- return System.Runtime.CompilerServices.JitHelpers.EnumEquals(x, y);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override int GetHashCode(T 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();
-
- internal override int IndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex + count;
- for (int i = startIndex; i < endIndex; i++)
- {
- if (System.Runtime.CompilerServices.JitHelpers.EnumEquals(array[i], value)) return i;
- }
- return -1;
- }
-
- internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
- {
- int endIndex = startIndex - count + 1;
- for (int i = startIndex; i >= endIndex; i--)
- {
- if (System.Runtime.CompilerServices.JitHelpers.EnumEquals(array[i], value)) return i;
- }
- return -1;
- }
- }
-}