// 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.Collections; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using HashHelpers = System.Numerics.Hashing.HashHelpers; namespace System { /// /// Helper so we can call some tuple methods recursively without knowing the underlying types. /// internal interface IValueTupleInternal : ITuple { int GetHashCode(IEqualityComparer comparer); string ToStringEnd(); } /// /// The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#. /// Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods. /// The System.ValueTuple types differ from the System.Tuple types in that: /// - they are structs rather than classes, /// - they are mutable rather than readonly, and /// - their members (such as Item1, Item2, etc) are fields rather than properties. /// [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, IValueTupleInternal, ITuple { /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if is a . public override bool Equals(object obj) { return obj is ValueTuple; } /// Returns a value indicating whether this instance is equal to a specified value. /// An instance to compare to this instance. /// true if has the same value as this instance; otherwise, false. public bool Equals(ValueTuple other) { return true; } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { return other is ValueTuple; } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return 0; } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { return 0; } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return 0; } /// Returns the hash code for this instance. /// A 32-bit signed integer hash code. public override int GetHashCode() { return 0; } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return 0; } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return 0; } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (). /// public override string ToString() { return "()"; } string IValueTupleInternal.ToStringEnd() { return ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 0; /// /// Get the element at position . /// object ITuple.this[int index] { get { throw new IndexOutOfRangeException(); } } /// Creates a new struct 0-tuple. /// A 0-tuple. public static ValueTuple Create() => new ValueTuple(); /// Creates a new struct 1-tuple, or singleton. /// The type of the first component of the tuple. /// The value of the first component of the tuple. /// A 1-tuple (singleton) whose value is (item1). public static ValueTuple Create(T1 item1) => new ValueTuple(item1); /// Creates a new struct 2-tuple, or pair. /// The type of the first component of the tuple. /// The type of the second component of the tuple. /// The value of the first component of the tuple. /// The value of the second component of the tuple. /// A 2-tuple (pair) whose value is (item1, item2). public static ValueTuple Create(T1 item1, T2 item2) => new ValueTuple(item1, item2); /// Creates a new struct 3-tuple, or triple. /// The type of the first component of the tuple. /// The type of the second component of the tuple. /// The type of the third component of the tuple. /// The value of the first component of the tuple. /// The value of the second component of the tuple. /// The value of the third component of the tuple. /// A 3-tuple (triple) whose value is (item1, item2, item3). public static ValueTuple Create(T1 item1, T2 item2, T3 item3) => new ValueTuple(item1, item2, item3); /// Creates a new struct 4-tuple, or quadruple. /// The type of the first component of the tuple. /// The type of the second component of the tuple. /// The type of the third component of the tuple. /// The type of the fourth component of the tuple. /// The value of the first component of the tuple. /// The value of the second component of the tuple. /// The value of the third component of the tuple. /// The value of the fourth component of the tuple. /// A 4-tuple (quadruple) whose value is (item1, item2, item3, item4). public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4) => new ValueTuple(item1, item2, item3, item4); /// Creates a new struct 5-tuple, or quintuple. /// The type of the first component of the tuple. /// The type of the second component of the tuple. /// The type of the third component of the tuple. /// The type of the fourth component of the tuple. /// The type of the fifth component of the tuple. /// The value of the first component of the tuple. /// The value of the second component of the tuple. /// The value of the third component of the tuple. /// The value of the fourth component of the tuple. /// The value of the fifth component of the tuple. /// A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5). public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) => new ValueTuple(item1, item2, item3, item4, item5); /// Creates a new struct 6-tuple, or sextuple. /// The type of the first component of the tuple. /// The type of the second component of the tuple. /// The type of the third component of the tuple. /// The type of the fourth component of the tuple. /// The type of the fifth component of the tuple. /// The type of the sixth component of the tuple. /// The value of the first component of the tuple. /// The value of the second component of the tuple. /// The value of the third component of the tuple. /// The value of the fourth component of the tuple. /// The value of the fifth component of the tuple. /// The value of the sixth component of the tuple. /// A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6). public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) => new ValueTuple(item1, item2, item3, item4, item5, item6); /// Creates a new struct 7-tuple, or septuple. /// The type of the first component of the tuple. /// The type of the second component of the tuple. /// The type of the third component of the tuple. /// The type of the fourth component of the tuple. /// The type of the fifth component of the tuple. /// The type of the sixth component of the tuple. /// The type of the seventh component of the tuple. /// The value of the first component of the tuple. /// The value of the second component of the tuple. /// The value of the third component of the tuple. /// The value of the fourth component of the tuple. /// The value of the fifth component of the tuple. /// The value of the sixth component of the tuple. /// The value of the seventh component of the tuple. /// A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7). public static ValueTuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) => new ValueTuple(item1, item2, item3, item4, item5, item6, item7); /// Creates a new struct 8-tuple, or octuple. /// The type of the first component of the tuple. /// The type of the second component of the tuple. /// The type of the third component of the tuple. /// The type of the fourth component of the tuple. /// The type of the fifth component of the tuple. /// The type of the sixth component of the tuple. /// The type of the seventh component of the tuple. /// The type of the eighth component of the tuple. /// The value of the first component of the tuple. /// The value of the second component of the tuple. /// The value of the third component of the tuple. /// The value of the fourth component of the tuple. /// The value of the fifth component of the tuple. /// The value of the sixth component of the tuple. /// The value of the seventh component of the tuple. /// The value of the eighth component of the tuple. /// An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8). public static ValueTuple> Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) => new ValueTuple>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8)); internal static int CombineHashCodes(int h1, int h2) { return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2); } internal static int CombineHashCodes(int h1, int h2, int h3) { return HashHelpers.Combine(CombineHashCodes(h1, h2), h3); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7); } internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) { return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8); } } /// Represents a 1-tuple, or singleton, as a value type. /// The type of the tuple's only component. [Serializable] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { /// /// The current instance's first component. /// public T1 Item1; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. public ValueTuple(T1 item1) { Item1 = item1; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current /// instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its field /// is equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; return Comparer.Default.Compare(Item1, objTuple.Item1); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { return Comparer.Default.Compare(Item1, other.Item1); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; return comparer.Compare(Item1, objTuple.Item1); } /// /// Returns the hash code for the current instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return Item1?.GetHashCode() ?? 0; } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return comparer.GetHashCode(Item1); } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return comparer.GetHashCode(Item1); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1), /// where Item1 represents the value of . If the field is , /// it is represented as . /// public override string ToString() { return "(" + Item1?.ToString() + ")"; } string IValueTupleInternal.ToStringEnd() { return Item1?.ToString() + ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 1; /// /// Get the element at position . /// object ITuple.this[int index] { get { if (index != 0) { throw new IndexOutOfRangeException(); } return Item1; } } } /// /// Represents a 2-tuple, or pair, as a value type. /// /// The type of the tuple's first component. /// The type of the tuple's second component. [Serializable] [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { /// /// The current instance's first component. /// public T1 Item1; /// /// The current instance's first component. /// public T2 Item2; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. /// The value of the tuple's second component. public ValueTuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its fields /// are equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1) && EqualityComparer.Default.Equals(Item2, other.Item2); } /// /// Returns a value that indicates whether the current instance is equal to a specified object based on a specified comparison method. /// /// The object to compare with this instance. /// An object that defines the method to use to evaluate whether the two objects are equal. /// if the current instance is equal to the specified object; otherwise, . /// /// /// This member is an explicit interface member implementation. It can be used only when the /// instance is cast to an interface. /// /// The implementation is called only if other is not , /// and if it can be successfully cast (in C#) or converted (in Visual Basic) to a /// whose components are of the same types as those of the current instance. The IStructuralEquatable.Equals(Object, IEqualityComparer) method /// first passes the values of the objects to be compared to the /// implementation. If this method call returns , the method is /// called again and passed the values of the two instances. /// bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1) && comparer.Equals(Item2, objTuple.Item2); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return CompareTo((ValueTuple)other); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { int c = Comparer.Default.Compare(Item1, other.Item1); if (c != 0) return c; return Comparer.Default.Compare(Item2, other.Item2); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; int c = comparer.Compare(Item1, objTuple.Item1); if (c != 0) return c; return comparer.Compare(Item2, objTuple.Item2); } /// /// Returns the hash code for the current instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2)); } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1, Item2), /// where Item1 and Item2 represent the values of the /// and fields. If either field value is , /// it is represented as . /// public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")"; } string IValueTupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 2; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; default: throw new IndexOutOfRangeException(); } } } } /// /// Represents a 3-tuple, or triple, as a value type. /// /// The type of the tuple's first component. /// The type of the tuple's second component. /// The type of the tuple's third component. [Serializable] [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { /// /// The current instance's first component. /// public T1 Item1; /// /// The current instance's second component. /// public T2 Item2; /// /// The current instance's third component. /// public T3 Item3; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. /// The value of the tuple's second component. /// The value of the tuple's third component. public ValueTuple(T1 item1, T2 item2, T3 item3) { Item1 = item1; Item2 = item2; Item3 = item3; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current /// instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its fields /// are equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1) && EqualityComparer.Default.Equals(Item2, other.Item2) && EqualityComparer.Default.Equals(Item3, other.Item3); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1) && comparer.Equals(Item2, objTuple.Item2) && comparer.Equals(Item3, objTuple.Item3); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return CompareTo((ValueTuple)other); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { int c = Comparer.Default.Compare(Item1, other.Item1); if (c != 0) return c; c = Comparer.Default.Compare(Item2, other.Item2); if (c != 0) return c; return Comparer.Default.Compare(Item3, other.Item3); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; int c = comparer.Compare(Item1, objTuple.Item1); if (c != 0) return c; c = comparer.Compare(Item2, objTuple.Item2); if (c != 0) return c; return comparer.Compare(Item3, objTuple.Item3); } /// /// Returns the hash code for the current instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3)); } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1, Item2, Item3). /// If any field value is , it is represented as . /// public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; } string IValueTupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 3; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; default: throw new IndexOutOfRangeException(); } } } } /// /// Represents a 4-tuple, or quadruple, as a value type. /// /// The type of the tuple's first component. /// The type of the tuple's second component. /// The type of the tuple's third component. /// The type of the tuple's fourth component. [Serializable] [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { /// /// The current instance's first component. /// public T1 Item1; /// /// The current instance's second component. /// public T2 Item2; /// /// The current instance's third component. /// public T3 Item3; /// /// The current instance's fourth component. /// public T4 Item4; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. /// The value of the tuple's second component. /// The value of the tuple's third component. /// The value of the tuple's fourth component. public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current /// instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its fields /// are equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1) && EqualityComparer.Default.Equals(Item2, other.Item2) && EqualityComparer.Default.Equals(Item3, other.Item3) && EqualityComparer.Default.Equals(Item4, other.Item4); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1) && comparer.Equals(Item2, objTuple.Item2) && comparer.Equals(Item3, objTuple.Item3) && comparer.Equals(Item4, objTuple.Item4); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return CompareTo((ValueTuple)other); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { int c = Comparer.Default.Compare(Item1, other.Item1); if (c != 0) return c; c = Comparer.Default.Compare(Item2, other.Item2); if (c != 0) return c; c = Comparer.Default.Compare(Item3, other.Item3); if (c != 0) return c; return Comparer.Default.Compare(Item4, other.Item4); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; int c = comparer.Compare(Item1, objTuple.Item1); if (c != 0) return c; c = comparer.Compare(Item2, objTuple.Item2); if (c != 0) return c; c = comparer.Compare(Item3, objTuple.Item3); if (c != 0) return c; return comparer.Compare(Item4, objTuple.Item4); } /// /// Returns the hash code for the current instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4)); } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1, Item2, Item3, Item4). /// If any field value is , it is represented as . /// public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; } string IValueTupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 4; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; default: throw new IndexOutOfRangeException(); } } } } /// /// Represents a 5-tuple, or quintuple, as a value type. /// /// The type of the tuple's first component. /// The type of the tuple's second component. /// The type of the tuple's third component. /// The type of the tuple's fourth component. /// The type of the tuple's fifth component. [Serializable] [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { /// /// The current instance's first component. /// public T1 Item1; /// /// The current instance's second component. /// public T2 Item2; /// /// The current instance's third component. /// public T3 Item3; /// /// The current instance's fourth component. /// public T4 Item4; /// /// The current instance's fifth component. /// public T5 Item5; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. /// The value of the tuple's second component. /// The value of the tuple's third component. /// The value of the tuple's fourth component. /// The value of the tuple's fifth component. public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current /// instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its fields /// are equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1) && EqualityComparer.Default.Equals(Item2, other.Item2) && EqualityComparer.Default.Equals(Item3, other.Item3) && EqualityComparer.Default.Equals(Item4, other.Item4) && EqualityComparer.Default.Equals(Item5, other.Item5); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1) && comparer.Equals(Item2, objTuple.Item2) && comparer.Equals(Item3, objTuple.Item3) && comparer.Equals(Item4, objTuple.Item4) && comparer.Equals(Item5, objTuple.Item5); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return CompareTo((ValueTuple)other); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { int c = Comparer.Default.Compare(Item1, other.Item1); if (c != 0) return c; c = Comparer.Default.Compare(Item2, other.Item2); if (c != 0) return c; c = Comparer.Default.Compare(Item3, other.Item3); if (c != 0) return c; c = Comparer.Default.Compare(Item4, other.Item4); if (c != 0) return c; return Comparer.Default.Compare(Item5, other.Item5); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; int c = comparer.Compare(Item1, objTuple.Item1); if (c != 0) return c; c = comparer.Compare(Item2, objTuple.Item2); if (c != 0) return c; c = comparer.Compare(Item3, objTuple.Item3); if (c != 0) return c; c = comparer.Compare(Item4, objTuple.Item4); if (c != 0) return c; return comparer.Compare(Item5, objTuple.Item5); } /// /// Returns the hash code for the current instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5)); } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5). /// If any field value is , it is represented as . /// public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; } string IValueTupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 5; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; default: throw new IndexOutOfRangeException(); } } } } /// /// Represents a 6-tuple, or sixtuple, as a value type. /// /// The type of the tuple's first component. /// The type of the tuple's second component. /// The type of the tuple's third component. /// The type of the tuple's fourth component. /// The type of the tuple's fifth component. /// The type of the tuple's sixth component. [Serializable] [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { /// /// The current instance's first component. /// public T1 Item1; /// /// The current instance's second component. /// public T2 Item2; /// /// The current instance's third component. /// public T3 Item3; /// /// The current instance's fourth component. /// public T4 Item4; /// /// The current instance's fifth component. /// public T5 Item5; /// /// The current instance's sixth component. /// public T6 Item6; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. /// The value of the tuple's second component. /// The value of the tuple's third component. /// The value of the tuple's fourth component. /// The value of the tuple's fifth component. /// The value of the tuple's sixth component. public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; Item6 = item6; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current /// instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its fields /// are equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1) && EqualityComparer.Default.Equals(Item2, other.Item2) && EqualityComparer.Default.Equals(Item3, other.Item3) && EqualityComparer.Default.Equals(Item4, other.Item4) && EqualityComparer.Default.Equals(Item5, other.Item5) && EqualityComparer.Default.Equals(Item6, other.Item6); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1) && comparer.Equals(Item2, objTuple.Item2) && comparer.Equals(Item3, objTuple.Item3) && comparer.Equals(Item4, objTuple.Item4) && comparer.Equals(Item5, objTuple.Item5) && comparer.Equals(Item6, objTuple.Item6); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return CompareTo((ValueTuple)other); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { int c = Comparer.Default.Compare(Item1, other.Item1); if (c != 0) return c; c = Comparer.Default.Compare(Item2, other.Item2); if (c != 0) return c; c = Comparer.Default.Compare(Item3, other.Item3); if (c != 0) return c; c = Comparer.Default.Compare(Item4, other.Item4); if (c != 0) return c; c = Comparer.Default.Compare(Item5, other.Item5); if (c != 0) return c; return Comparer.Default.Compare(Item6, other.Item6); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; int c = comparer.Compare(Item1, objTuple.Item1); if (c != 0) return c; c = comparer.Compare(Item2, objTuple.Item2); if (c != 0) return c; c = comparer.Compare(Item3, objTuple.Item3); if (c != 0) return c; c = comparer.Compare(Item4, objTuple.Item4); if (c != 0) return c; c = comparer.Compare(Item5, objTuple.Item5); if (c != 0) return c; return comparer.Compare(Item6, objTuple.Item6); } /// /// Returns the hash code for the current instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6)); } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6). /// If any field value is , it is represented as . /// public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; } string IValueTupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 6; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; case 5: return Item6; default: throw new IndexOutOfRangeException(); } } } } /// /// Represents a 7-tuple, or sentuple, as a value type. /// /// The type of the tuple's first component. /// The type of the tuple's second component. /// The type of the tuple's third component. /// The type of the tuple's fourth component. /// The type of the tuple's fifth component. /// The type of the tuple's sixth component. /// The type of the tuple's seventh component. [Serializable] [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple { /// /// The current instance's first component. /// public T1 Item1; /// /// The current instance's second component. /// public T2 Item2; /// /// The current instance's third component. /// public T3 Item3; /// /// The current instance's fourth component. /// public T4 Item4; /// /// The current instance's fifth component. /// public T5 Item5; /// /// The current instance's sixth component. /// public T6 Item6; /// /// The current instance's seventh component. /// public T7 Item7; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. /// The value of the tuple's second component. /// The value of the tuple's third component. /// The value of the tuple's fourth component. /// The value of the tuple's fifth component. /// The value of the tuple's sixth component. /// The value of the tuple's seventh component. public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; Item6 = item6; Item7 = item7; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current /// instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its fields /// are equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1) && EqualityComparer.Default.Equals(Item2, other.Item2) && EqualityComparer.Default.Equals(Item3, other.Item3) && EqualityComparer.Default.Equals(Item4, other.Item4) && EqualityComparer.Default.Equals(Item5, other.Item5) && EqualityComparer.Default.Equals(Item6, other.Item6) && EqualityComparer.Default.Equals(Item7, other.Item7); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1) && comparer.Equals(Item2, objTuple.Item2) && comparer.Equals(Item3, objTuple.Item3) && comparer.Equals(Item4, objTuple.Item4) && comparer.Equals(Item5, objTuple.Item5) && comparer.Equals(Item6, objTuple.Item6) && comparer.Equals(Item7, objTuple.Item7); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return CompareTo((ValueTuple)other); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { int c = Comparer.Default.Compare(Item1, other.Item1); if (c != 0) return c; c = Comparer.Default.Compare(Item2, other.Item2); if (c != 0) return c; c = Comparer.Default.Compare(Item3, other.Item3); if (c != 0) return c; c = Comparer.Default.Compare(Item4, other.Item4); if (c != 0) return c; c = Comparer.Default.Compare(Item5, other.Item5); if (c != 0) return c; c = Comparer.Default.Compare(Item6, other.Item6); if (c != 0) return c; return Comparer.Default.Compare(Item7, other.Item7); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; int c = comparer.Compare(Item1, objTuple.Item1); if (c != 0) return c; c = comparer.Compare(Item2, objTuple.Item2); if (c != 0) return c; c = comparer.Compare(Item3, objTuple.Item3); if (c != 0) return c; c = comparer.Compare(Item4, objTuple.Item4); if (c != 0) return c; c = comparer.Compare(Item5, objTuple.Item5); if (c != 0) return c; c = comparer.Compare(Item6, objTuple.Item6); if (c != 0) return c; return comparer.Compare(Item7, objTuple.Item7); } /// /// Returns the hash code for the current instance. /// /// A 32-bit signed integer hash code. public override int GetHashCode() { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } private int GetHashCodeCore(IEqualityComparer comparer) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7)); } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7). /// If any field value is , it is represented as . /// public override string ToString() { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; } string IValueTupleInternal.ToStringEnd() { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")"; } /// /// The number of positions in this data structure. /// int ITuple.Length => 7; /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; case 5: return Item6; case 6: return Item7; default: throw new IndexOutOfRangeException(); } } } } /// /// Represents an 8-tuple, or octuple, as a value type. /// /// The type of the tuple's first component. /// The type of the tuple's second component. /// The type of the tuple's third component. /// The type of the tuple's fourth component. /// The type of the tuple's fifth component. /// The type of the tuple's sixth component. /// The type of the tuple's seventh component. /// The type of the tuple's eighth component. [Serializable] [StructLayout(LayoutKind.Auto)] [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] public struct ValueTuple : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, IValueTupleInternal, ITuple where TRest : struct { /// /// The current instance's first component. /// public T1 Item1; /// /// The current instance's second component. /// public T2 Item2; /// /// The current instance's third component. /// public T3 Item3; /// /// The current instance's fourth component. /// public T4 Item4; /// /// The current instance's fifth component. /// public T5 Item5; /// /// The current instance's sixth component. /// public T6 Item6; /// /// The current instance's seventh component. /// public T7 Item7; /// /// The current instance's eighth component. /// public TRest Rest; /// /// Initializes a new instance of the value type. /// /// The value of the tuple's first component. /// The value of the tuple's second component. /// The value of the tuple's third component. /// The value of the tuple's fourth component. /// The value of the tuple's fifth component. /// The value of the tuple's sixth component. /// The value of the tuple's seventh component. /// The value of the tuple's eight component. public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { if (!(rest is IValueTupleInternal)) { throw new ArgumentException(SR.ArgumentException_ValueTupleLastArgumentNotAValueTuple); } Item1 = item1; Item2 = item2; Item3 = item3; Item4 = item4; Item5 = item5; Item6 = item6; Item7 = item7; Rest = rest; } /// /// Returns a value that indicates whether the current instance is equal to a specified object. /// /// The object to compare with this instance. /// if the current instance is equal to the specified object; otherwise, . /// /// The parameter is considered to be equal to the current instance under the following conditions: /// /// It is a value type. /// Its components are of the same types as those of the current instance. /// Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component. /// /// public override bool Equals(object obj) { return obj is ValueTuple && Equals((ValueTuple)obj); } /// /// Returns a value that indicates whether the current /// instance is equal to a specified . /// /// The tuple to compare with this instance. /// if the current instance is equal to the specified tuple; otherwise, . /// /// The parameter is considered to be equal to the current instance if each of its fields /// are equal to that of the current instance, using the default comparer for that field's type. /// public bool Equals(ValueTuple other) { return EqualityComparer.Default.Equals(Item1, other.Item1) && EqualityComparer.Default.Equals(Item2, other.Item2) && EqualityComparer.Default.Equals(Item3, other.Item3) && EqualityComparer.Default.Equals(Item4, other.Item4) && EqualityComparer.Default.Equals(Item5, other.Item5) && EqualityComparer.Default.Equals(Item6, other.Item6) && EqualityComparer.Default.Equals(Item7, other.Item7) && EqualityComparer.Default.Equals(Rest, other.Rest); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { if (other == null || !(other is ValueTuple)) return false; var objTuple = (ValueTuple)other; return comparer.Equals(Item1, objTuple.Item1) && comparer.Equals(Item2, objTuple.Item2) && comparer.Equals(Item3, objTuple.Item3) && comparer.Equals(Item4, objTuple.Item4) && comparer.Equals(Item5, objTuple.Item5) && comparer.Equals(Item6, objTuple.Item6) && comparer.Equals(Item7, objTuple.Item7) && comparer.Equals(Rest, objTuple.Rest); } int IComparable.CompareTo(object other) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } return CompareTo((ValueTuple)other); } /// Compares this instance to a specified instance and returns an indication of their relative values. /// An instance to compare. /// /// A signed number indicating the relative values of this instance and . /// Returns less than zero if this instance is less than , zero if this /// instance is equal to , and greater than zero if this instance is greater /// than . /// public int CompareTo(ValueTuple other) { int c = Comparer.Default.Compare(Item1, other.Item1); if (c != 0) return c; c = Comparer.Default.Compare(Item2, other.Item2); if (c != 0) return c; c = Comparer.Default.Compare(Item3, other.Item3); if (c != 0) return c; c = Comparer.Default.Compare(Item4, other.Item4); if (c != 0) return c; c = Comparer.Default.Compare(Item5, other.Item5); if (c != 0) return c; c = Comparer.Default.Compare(Item6, other.Item6); if (c != 0) return c; c = Comparer.Default.Compare(Item7, other.Item7); if (c != 0) return c; return Comparer.Default.Compare(Rest, other.Rest); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { if (other == null) return 1; if (!(other is ValueTuple)) { throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other)); } var objTuple = (ValueTuple)other; int c = comparer.Compare(Item1, objTuple.Item1); if (c != 0) return c; c = comparer.Compare(Item2, objTuple.Item2); if (c != 0) return c; c = comparer.Compare(Item3, objTuple.Item3); if (c != 0) return c; c = comparer.Compare(Item4, objTuple.Item4); if (c != 0) return c; c = comparer.Compare(Item5, objTuple.Item5); if (c != 0) return c; c = comparer.Compare(Item6, objTuple.Item6); if (c != 0) return c; c = comparer.Compare(Item7, objTuple.Item7); if (c != 0) return c; return comparer.Compare(Rest, objTuple.Rest); } /// /// Returns the hash code for the current instance. /// /// 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 IValueTupleInternal rest = Rest as IValueTupleInternal; if (rest == null) { return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0); } int size = rest.Length; if (size >= 8) { return rest.GetHashCode(); } // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest int k = 8 - size; switch (k) { case 1: return ValueTuple.CombineHashCodes(Item7?.GetHashCode() ?? 0, rest.GetHashCode()); case 2: return ValueTuple.CombineHashCodes(Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, rest.GetHashCode()); case 3: return ValueTuple.CombineHashCodes(Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, rest.GetHashCode()); case 4: return ValueTuple.CombineHashCodes(Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, rest.GetHashCode()); case 5: return ValueTuple.CombineHashCodes(Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, rest.GetHashCode()); case 6: return ValueTuple.CombineHashCodes(Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, rest.GetHashCode()); case 7: case 8: return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0, Item2?.GetHashCode() ?? 0, Item3?.GetHashCode() ?? 0, Item4?.GetHashCode() ?? 0, Item5?.GetHashCode() ?? 0, Item6?.GetHashCode() ?? 0, Item7?.GetHashCode() ?? 0, rest.GetHashCode()); } Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); return -1; } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(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 IValueTupleInternal rest = Rest as IValueTupleInternal; if (rest == null) { return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7)); } int size = rest.Length; if (size >= 8) { return rest.GetHashCode(comparer); } // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest int k = 8 - size; switch (k) { case 1: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); case 2: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); case 3: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); case 4: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); case 5: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); case 6: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); case 7: case 8: return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer)); } Contract.Assert(false, "Missed all cases for computing ValueTuple hash code"); return -1; } int IValueTupleInternal.GetHashCode(IEqualityComparer comparer) { return GetHashCodeCore(comparer); } /// /// Returns a string that represents the value of this instance. /// /// The string representation of this instance. /// /// The string returned by this method takes the form (Item1, Item2, Item3, Item4, Item5, Item6, Item7, Rest). /// If any field value is , it is represented as . /// public override string ToString() { IValueTupleInternal rest = Rest as IValueTupleInternal; if (rest == null) { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; } else { return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); } } string IValueTupleInternal.ToStringEnd() { IValueTupleInternal rest = Rest as IValueTupleInternal; if (rest == null) { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")"; } else { return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd(); } } /// /// The number of positions in this data structure. /// int ITuple.Length { get { IValueTupleInternal rest = Rest as IValueTupleInternal; return rest == null ? 8 : 7 + rest.Length; } } /// /// Get the element at position . /// object ITuple.this[int index] { get { switch (index) { case 0: return Item1; case 1: return Item2; case 2: return Item3; case 3: return Item4; case 4: return Item5; case 5: return Item6; case 6: return Item7; } IValueTupleInternal rest = Rest as IValueTupleInternal; if (rest == null) { if (index == 7) { return Rest; } throw new IndexOutOfRangeException(); } return rest[index - 7]; } } } }