Browse Source

Give EquatableArray content-based equality and hashing

The default struct GetHashCode hashes the array reference, which would
break the records that cache these arrays as incremental-generator keys.
pull/3807/head
Siegfried Pammer 3 weeks ago committed by Siegfried Pammer
parent
commit
9a17ecce1a
  1. 27
      ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs

27
ICSharpCode.Decompiler.Generators/DecompilerSyntaxTreeGenerator.cs

@ -800,9 +800,34 @@ readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T @@ -800,9 +800,34 @@ readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T
public bool Equals(EquatableArray<T> other)
{
return other.array.AsSpan().SequenceEqual(this.array);
return this.array.AsSpan().SequenceEqual(other.array.AsSpan());
}
public override bool Equals(object obj)
{
return obj is EquatableArray<T> other && Equals(other);
}
// Content-based hash so it agrees with the content-based Equals; the default struct
// GetHashCode would hash the array reference and break the records that cache these as
// incremental-generator keys. (System.HashCode is unavailable on netstandard2.0.)
public override int GetHashCode()
{
if (array == null)
return 0;
unchecked
{
int hash = 17;
foreach (T item in array)
hash = hash * 31 + EqualityComparer<T>.Default.GetHashCode(item);
return hash;
}
}
public static bool operator ==(EquatableArray<T> left, EquatableArray<T> right) => left.Equals(right);
public static bool operator !=(EquatableArray<T> left, EquatableArray<T> right) => !left.Equals(right);
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)array).GetEnumerator();

Loading…
Cancel
Save