diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..e39123006ea95abcd65bbf24ebcaaa9bf1478ae6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+### ifoxcad的扩展包,用于支持低版本
+
+
+### 目前仅向下兼容到net4.0未能兼容到4.5
+
+### 元组
+
+修改元组的支持逻辑,将需要添加元组的低版本的`DefineConstants`中添加`USEVALUETUPLE`条件编译符号即可支持元组功能
\ No newline at end of file
diff --git a/src/CAD/IFox.CAD.Ex.Shared/CLS/TupleElementNamesAttribute.cs b/src/CAD/IFox.CAD.Ex.Shared/CLS/TupleElementNamesAttribute.cs
new file mode 100644
index 0000000000000000000000000000000000000000..93e61930c31b8277948fa060629cb1d813a04ba1
--- /dev/null
+++ b/src/CAD/IFox.CAD.Ex.Shared/CLS/TupleElementNamesAttribute.cs
@@ -0,0 +1,48 @@
+// 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.
+
+namespace System.Runtime.CompilerServices;
+
+///
+/// Indicates that the use of on a member is meant to be treated as a tuple with element names.
+///
+[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event)]
+public sealed class TupleElementNamesAttribute : Attribute
+{
+ private readonly string[] _transformNames;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// Specifies, in a pre-order depth-first traversal of a type's
+ /// construction, which occurrences are
+ /// meant to carry element names.
+ ///
+ ///
+ /// This constructor is meant to be used on types that contain an
+ /// instantiation of that contains
+ /// element names. For instance, if C is a generic type with
+ /// two type parameters, then a use of the constructed type C{, might be intended to
+ /// treat the first type argument as a tuple with element names and the
+ /// second as a tuple without element names. In which case, the
+ /// appropriate attribute specification should use a
+ /// transformNames value of { "name1", "name2", null, null,
+ /// null }.
+ ///
+ public TupleElementNamesAttribute(string[] transformNames)
+ {
+ _transformNames = transformNames ?? throw new ArgumentNullException(nameof(transformNames));
+ }
+
+ ///
+ /// Specifies, in a pre-order depth-first traversal of a type's
+ /// construction, which elements are
+ /// meant to carry element names.
+ ///
+ public IList TransformNames => _transformNames;
+}
\ No newline at end of file
diff --git a/src/CAD/IFox.CAD.Ex.Shared/CLS/ValueTuple.cs b/src/CAD/IFox.CAD.Ex.Shared/CLS/ValueTuple.cs
new file mode 100644
index 0000000000000000000000000000000000000000..89cc14cc130703b572a8425859cdeb857c8cc810
--- /dev/null
+++ b/src/CAD/IFox.CAD.Ex.Shared/CLS/ValueTuple.cs
@@ -0,0 +1,2152 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// #pragma warning disable SA1141 // explicitly not using tuple syntax in tuple implementation
+#if USEVALUETUPLE
+
+using System.Diagnostics;
+using System.Numerics.Hashing;
+/*
+ * 惊惊:
+ * 首先是因为有人想要编译的时候只形成一个dll,然后把元组塞入IFox,同时也补充了NET35没有元组的遗憾.
+ *
+ * 而利用nuget元组包必然会形成依赖地狱.
+ *
+ * 如果你的工程使用了nuget元组包,就造成了必须要剔除IFox.
+ *
+ * 改IFox的元组命名空间倒是可以分离两者,但是 vs编译器 无法识别带其他命名空间的元组.
+ * 所以元组本身就是冲突的,需要把其他元组卸载掉,由IFox提供.
+ */
+
+/*
+ * 1. 元组是net47之后提供的特性,所以net47之前的版本是都没有的
+ * 2. 通过定义常量的办法将元组屏蔽,很奇怪的是源码包可以,但是普通包不行,所以推荐使用源码包 index和range的情况类似
+ * 这种问题就没有很好的解决方式,因为用了ifox就不能用其他的index,range,valuetuple类库,但是其他的三方库却依赖
+ * 这些类库,所以还是使用源码包吧。
+*/
+
+#if NET35
+namespace System.Collections
+{
+ public interface IStructuralComparable
+ {
+ int CompareTo(object? other, IComparer comparer);
+ }
+ public interface IStructuralEquatable
+ {
+ bool Equals(object? other, IEqualityComparer comparer);
+ int GetHashCode(IEqualityComparer comparer);
+ }
+}
+#endif
+
+
+
+namespace System.Numerics.Hashing
+{
+ internal static class HashHelpers
+ {
+ public static readonly int RandomSeed = Guid.NewGuid().GetHashCode();
+
+ public static int Combine(int h1, int h2)
+ {
+ unchecked
+ {
+ // RyuJIT optimizes this to use the ROL instruction
+ // Related GitHub pull request: dotnet/coreclr#1830
+
+ // RyuJIT 对此进行了优化以使用 ROL 指令
+ // 相关 GitHub 拉取请求:dotnet/coreclr#1830
+ uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27);
+ return ((int)rol5 + h1) ^ h2;
+ }
+ }
+ }
+}
+
+
+
+
+namespace System
+{
+
+ // internal static class SR
+ internal sealed partial class SR
+ {
+ // public const string ArgumentException_ValueTupleIncorrectType = "The parameter should be a ValueTuple type of appropriate arity.";
+ // public const string ArgumentException_ValueTupleLastArgumentNotAValueTuple = "The TRest type argument of ValueTuple`8 must be a ValueTuple.";
+ public const string ArgumentException_ValueTupleIncorrectType = "该参数应该是适当数量的 ValueTuple 类型.";
+ public const string ArgumentException_ValueTupleLastArgumentNotAValueTuple = "ValueTuple`8 的 TREST 类型参数必须是 ValueTuple.";
+ }
+
+ // Helper so we can call some tuple methods recursively without knowing the underlying types.
+ ///
+ /// 帮助器,因此我们可以在不知道底层类型的情况下递归调用一些元组方法.
+ ///
+ internal interface ITupleInternal
+ {
+ int GetHashCode(IEqualityComparer comparer);
+ int Size { get; }
+ 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.
+ ///
+ /// ValueTuple 类型(从 arity 0 到 8)包含运行时实现,它是 C# 中的元组和 F# 中的结构元组的基础.
+ /// 除了通过语言语法创建之外,它们最容易通过 ValueTuple.Create 工厂方法创建.
+ /// System.ValueTuple 类型与 System.Tuple 类型的不同之处在于:
+ /// - 它们是结构而不是类,
+ /// - 它们是可变的而不是只读的,并且
+ /// - 它们的成员(例如 Item1、Item2 等)是字段而不是属性.
+ ///
+ public struct ValueTuple
+ : IEquatable, IStructuralEquatable, IStructuralComparable, IComparable, IComparable, ITupleInternal
+ {
+ ///
+ /// 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return ")";
+ }
+
+ int ITupleInternal.Size => 0;
+
+ /// Creates a new struct 0-tuple.
+ /// A 0-tuple.
+ public static ValueTuple Create() => new();
+
+ /// 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(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(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(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(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(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(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(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(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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ {
+ ///
+ /// 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 EqualityComparer.Default.GetHashCode(Item1);
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return comparer.GetHashCode(Item1);
+ }
+
+ int ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ")";
+ }
+
+ int ITupleInternal.Size => 1;
+ }
+
+ ///
+ /// 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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ {
+ ///
+ /// 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 is null or not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2));
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
+ comparer.GetHashCode(Item2));
+ }
+
+ int ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ")";
+ }
+
+ int ITupleInternal.Size => 2;
+ }
+
+ ///
+ /// 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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ {
+ ///
+ /// 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3));
+ }
+
+ 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 ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
+ }
+
+ int ITupleInternal.Size => 3;
+ }
+
+ ///
+ /// 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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ {
+ ///
+ /// 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4));
+ }
+
+ 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 ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
+ }
+
+ int ITupleInternal.Size => 4;
+ }
+
+ ///
+ /// 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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ {
+ ///
+ /// 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5));
+ }
+
+ 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 ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
+ }
+
+ int ITupleInternal.Size => 5;
+ }
+
+ ///
+ /// 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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ {
+ ///
+ /// 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6));
+ }
+
+ 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 ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
+ }
+
+ int ITupleInternal.Size => 6;
+ }
+
+ ///
+ /// 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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ {
+ ///
+ /// 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7));
+ }
+
+ 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 ITupleInternal.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 ITupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
+ }
+
+ int ITupleInternal.Size => 7;
+ }
+
+ ///
+ /// 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.
+ public struct ValueTuple
+ : IEquatable>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable>, ITupleInternal
+ 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 not ITupleInternal)
+ {
+ 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 tuple && Equals(tuple);
+ }
+
+ ///
+ /// 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 not 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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 not ValueTuple)
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleIncorrectType, 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
+ if (Rest is not ITupleInternal rest)
+ {
+ return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7));
+ }
+
+ int size = rest.Size;
+ 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(EqualityComparer.Default.GetHashCode(Item7),
+ rest.GetHashCode());
+ case 2:
+ return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7),
+ rest.GetHashCode());
+ case 3:
+ return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7),
+ rest.GetHashCode());
+ case 4:
+ return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7),
+ rest.GetHashCode());
+ case 5:
+ return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7),
+ rest.GetHashCode());
+ case 6:
+ return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7),
+ rest.GetHashCode());
+ case 7:
+ case 8:
+ return ValueTuple.CombineHashCodes(EqualityComparer.Default.GetHashCode(Item1),
+ EqualityComparer.Default.GetHashCode(Item2),
+ EqualityComparer.Default.GetHashCode(Item3),
+ EqualityComparer.Default.GetHashCode(Item4),
+ EqualityComparer.Default.GetHashCode(Item5),
+ EqualityComparer.Default.GetHashCode(Item6),
+ EqualityComparer.Default.GetHashCode(Item7),
+ rest.GetHashCode());
+ }
+
+ Debug.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
+ if (Rest is not ITupleInternal rest)
+ {
+ 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.Size;
+ 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));
+ }
+
+ Debug.Assert(false, "Missed all cases for computing ValueTuple hash code");
+ return -1;
+ }
+
+ int ITupleInternal.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()
+ {
+ if (Rest is not ITupleInternal rest)
+ {
+ 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 ITupleInternal.ToStringEnd()
+ {
+ if (Rest is not ITupleInternal rest)
+ {
+ 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();
+ }
+ }
+
+ int ITupleInternal.Size
+ {
+ get
+ {
+ // ITupleInternal? rest = Rest as ITupleInternal;
+ // return rest == null ? 8 : 7 + rest.Size;
+ return Rest is not ITupleInternal rest ? 8 : 7 + rest.Size;
+ }
+ }
+ }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.projitems b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.projitems
new file mode 100644
index 0000000000000000000000000000000000000000..8ba124523841c17589c3a709cfa888a0c1fd9f38
--- /dev/null
+++ b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.projitems
@@ -0,0 +1,15 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ 65027894-6aa5-4389-86f7-d418d60465fd
+
+
+ IFox.CAD.Ex.Shared
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.projitems2 b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.projitems2
new file mode 100644
index 0000000000000000000000000000000000000000..c77cbc0db6addd99b35ac4e60c115857dd46af3c
--- /dev/null
+++ b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.projitems2
@@ -0,0 +1,95 @@
+
+
+
+ $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
+ true
+ 20f254f7-aee5-42ae-a9b3-149bbdc7397f
+
+
+ IFox.CAD.Shared
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.shproj b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.shproj
new file mode 100644
index 0000000000000000000000000000000000000000..388a070e3f6618b8190737df55a80395473123fd
--- /dev/null
+++ b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.shproj
@@ -0,0 +1,13 @@
+
+
+
+ 65027894-6aa5-4389-86f7-d418d60465fd
+ 14.0
+
+
+
+
+
+
+
+
diff --git a/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.sln b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.sln
new file mode 100644
index 0000000000000000000000000000000000000000..2acf57bb32fa7631bdc38481c84f134762f81a7f
--- /dev/null
+++ b/src/CAD/IFox.CAD.Ex.Shared/IFox.CAD.Ex.Shared.sln
@@ -0,0 +1,18 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32901.215
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharedProject1", "SharedProject1.shproj", "{65027894-6AA5-4389-86F7-D418D60465FD}"
+EndProject
+Global
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {47D994AC-D220-42F4-B786-9C3DFFA6B72A}
+ EndGlobalSection
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ SharedProject1.projitems*{65027894-6aa5-4389-86f7-d418d60465fd}*SharedItemsImports = 13
+ EndGlobalSection
+EndGlobal