diff --git a/src/System.Private.CoreLib/shared/System/ValueTuple.cs b/src/System.Private.CoreLib/shared/System/ValueTuple.cs index 9792b840a801..c16b2e01e4c3 100644 --- a/src/System.Private.CoreLib/shared/System/ValueTuple.cs +++ b/src/System.Private.CoreLib/shared/System/ValueTuple.cs @@ -2054,8 +2054,8 @@ int IStructuralComparable.CompareTo(object? other, IComparer comparer) /// A 32-bit signed integer hash code. public override int GetHashCode() { - // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple - if (!(Rest is IValueTupleInternal rest)) + // We want to have a limited hash in this case. We'll use the first 7 elements of the tuple + if (!(Rest is IValueTupleInternal)) { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, @@ -2066,38 +2066,42 @@ public override int GetHashCode() Item7?.GetHashCode() ?? 0); } - int size = rest.Length; - if (size >= 8) { return rest.GetHashCode(); } + int size = ((IValueTupleInternal)Rest).Length; + int restHashCode = Rest.GetHashCode(); + if (size >= 8) + { + return restHashCode; + } - // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest + // In this case, the rest member has less than 8 elements so we need to combine some of our elements with the elements in rest int k = 8 - size; switch (k) { case 1: return ValueTuple.CombineHashCodes(Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); + restHashCode); case 2: return ValueTuple.CombineHashCodes(Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); + restHashCode); case 3: return ValueTuple.CombineHashCodes(Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); + restHashCode); case 4: return ValueTuple.CombineHashCodes(Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); + restHashCode); case 5: return ValueTuple.CombineHashCodes(Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); + restHashCode); case 6: return ValueTuple.CombineHashCodes(Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, @@ -2105,7 +2109,7 @@ public override int GetHashCode() Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); + restHashCode); case 7: case 8: return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, @@ -2115,7 +2119,7 @@ public override int GetHashCode() Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, - rest.GetHashCode()); + restHashCode); } Debug.Fail("Missed all cases for computing ValueTuple hash code"); @@ -2129,7 +2133,7 @@ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) private int GetHashCodeCore(IEqualityComparer comparer) { - // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple + // We want to have a limited hash in this case. We'll use the first 7 elements of the tuple if (!(Rest is IValueTupleInternal rest)) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1!), comparer.GetHashCode(Item2!), comparer.GetHashCode(Item3!), @@ -2187,9 +2191,9 @@ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) /// public override string ToString() { - if (Rest is IValueTupleInternal rest) + if (Rest is IValueTupleInternal) { - return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); + return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + ((IValueTupleInternal)Rest).ToStringEnd(); } return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; @@ -2197,9 +2201,9 @@ public override string ToString() string IValueTupleInternal.ToStringEnd() { - if (Rest is IValueTupleInternal rest) + if (Rest is IValueTupleInternal) { - return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); + return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + ((IValueTupleInternal)Rest).ToStringEnd(); } return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; @@ -2208,7 +2212,7 @@ string IValueTupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - int ITuple.Length => Rest is IValueTupleInternal rest ? 7 + rest.Length : 8; + int ITuple.Length => Rest is IValueTupleInternal ? 7 + ((IValueTupleInternal)Rest).Length : 8; /// /// Get the element at position . @@ -2235,9 +2239,9 @@ string IValueTupleInternal.ToStringEnd() return Item7; } - if (Rest is IValueTupleInternal rest) + if (Rest is IValueTupleInternal) { - return rest[index - 7]; + return ((IValueTupleInternal)Rest)[index - 7]; }