From 669260f5385d291f9eecdadcce658d4753465668 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Thu, 14 Jul 2016 15:07:06 -0700 Subject: [PATCH] Using ITuple as constraint on TRest --- .../src/System/ValueTuple/TupleExtensions.cs | 2 +- .../src/System/ValueTuple/ValueTuple.cs | 51 ++++++++----------- .../tests/ValueTuple/UnitTests.cs | 39 +++++++++++--- 3 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs b/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs index 096df957124a..9cd91201fc2d 100644 --- a/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs +++ b/src/System.ValueTuple/src/System/ValueTuple/TupleExtensions.cs @@ -920,7 +920,7 @@ public static Tuple CreateLong(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct => + private static ValueTuple CreateLong(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct, ITuple => new ValueTuple(item1, item2, item3, item4, item5, item6, item7, rest); private static Tuple CreateLongRef(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) => diff --git a/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs b/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs index 2558d1b32f86..7fd60e42321c 100644 --- a/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs +++ b/src/System.ValueTuple/src/System/ValueTuple/ValueTuple.cs @@ -141,12 +141,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 0; + int ITuple.Length => 0; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -451,12 +451,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 1; + int ITuple.Length => 1; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -654,12 +654,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 2; + int ITuple.Length => 2; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -857,12 +857,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 3; + int ITuple.Length => 3; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -1079,12 +1079,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 4; + int ITuple.Length => 4; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -1320,12 +1320,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 5; + int ITuple.Length => 5; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -1580,12 +1580,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 6; + int ITuple.Length => 6; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -1859,12 +1859,12 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length => 7; + int ITuple.Length => 7; /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -1904,7 +1904,7 @@ public object this[int index] /// The type of the tuple's eigth component. public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal, ITuple - where TRest : struct + where TRest : struct, ITuple { /// /// The current instance's first component. @@ -2272,19 +2272,18 @@ string ITupleInternal.ToStringEnd() /// /// The number of positions in this data structure. /// - public int Length + int ITuple.Length { get { - ITupleInternal rest = Rest as ITupleInternal; - return rest == null ? 8 : 7 + rest.Length; + return 7 + ((ITuple)Rest).Length; } } /// /// Get the element at position . /// - public object this[int index] + object ITuple.this[int index] { get { @@ -2306,15 +2305,7 @@ public object this[int index] return Item7; } - ITupleInternal rest = Rest as ITupleInternal; - if (index > 0 && index < Length && rest != null) - { - return rest[index - 7]; - } - else - { - throw new IndexOutOfRangeException(); - } + return ((ITuple)Rest)[index - 7]; } } } diff --git a/src/System.ValueTuple/tests/ValueTuple/UnitTests.cs b/src/System.ValueTuple/tests/ValueTuple/UnitTests.cs index a2bbafd8251e..8935d04a67d1 100644 --- a/src/System.ValueTuple/tests/ValueTuple/UnitTests.cs +++ b/src/System.ValueTuple/tests/ValueTuple/UnitTests.cs @@ -995,7 +995,7 @@ public static void SevenTuples() Assert.Throws(() => it[7]); } - public static ValueTuple CreateLong(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct => + public static ValueTuple CreateLong(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct, ITuple => new ValueTuple(item1, item2, item3, item4, item5, item6, item7, rest); public static Tuple CreateLongRef(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) => @@ -1147,12 +1147,11 @@ public static void LongTuplesWithNull() [Fact] public static void EightTuplesWithBadRest() { - var d = default(ValueTuple); + var d = default(ValueTuple); d.Item1 = 1; - d.Rest = 42; Assert.Equal(35937, d.GetHashCode()); Assert.Equal(35937, ((IStructuralEquatable)d).GetHashCode()); - Assert.Equal("(1, 0, 0, 0, 0, 0, 0, 42)", d.ToString()); + Assert.Equal("(1, 0, 0, 0, 0, 0, 0, BadTuple)", d.ToString()); Assert.Equal(35937, CreateLong(1, 2, 3, 4, 5, 6, 7, d).GetHashCode()); @@ -1160,7 +1159,7 @@ public static void EightTuplesWithBadRest() Assert.Equal(ValueTuple.Create(1, 0, 0, 0, 0, 0, 0).GetHashCode(), d.GetHashCode()); Assert.Equal(((IStructuralEquatable)ValueTuple.Create(1, 0, 0, 0, 0, 0, 0)).GetHashCode(TestEqualityComparer.Instance), ((IStructuralEquatable)d).GetHashCode(TestEqualityComparer.Instance)); - Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 0, 0, 0, 0, 0, 0, 42)", CreateLong(1, 2, 3, 4, 5, 6, 7, d).ToString()); + Assert.Equal("(1, 2, 3, 4, 5, 6, 7, 1, 0, 0, 0, 0, 0, 0, BadTuple)", CreateLong(1, 2, 3, 4, 5, 6, 7, d).ToString()); ITuple it = d; Assert.Throws(() => it[-1]); @@ -1171,7 +1170,35 @@ public static void EightTuplesWithBadRest() Assert.Equal(0, it[4]); Assert.Equal(0, it[5]); Assert.Equal(0, it[6]); - Assert.Throws(() => it[7]); + Assert.Equal(42, it[7]); + Assert.Throws(() => it[8]); + } + + private struct BadTuple : ITuple + { + // doesn't implement ITupleInternal + + int ITuple.Length => 1; + + object ITuple.this[int index] + { + get + { + if (index == 0) + { + return 42; + } + else + { + throw new IndexOutOfRangeException(); + } + } + } + + public override string ToString() + { + return "BadTuple"; + } } private class TestClass : IComparable