#if NET20 || NET30 || NET35 || !NET_4_6 using System.Collections; using System.Collections.Generic; using System.Globalization; namespace System { [Serializable] public class Tuple : IStructuralEquatable, IStructuralComparable, IComparable { private readonly T1 _item1; private readonly T2 _item2; public Tuple(T1 item1, T2 item2) { _item1 = item1; _item2 = item2; } public T1 Item1 { get { return _item1; } } public T2 Item2 { get { return _item2; } } public override bool Equals(object obj) { return ((IStructuralEquatable)this).Equals(obj, EqualityComparer.Default); } public override int GetHashCode() { return ((IStructuralEquatable)this).GetHashCode(EqualityComparer.Default); } int IStructuralComparable.CompareTo(object other, IComparer comparer) { return CompareTo(other, comparer); } bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer) { var tuple = other as Tuple; if (tuple == null) { return false; } return comparer.Equals(_item1, tuple._item1) && comparer.Equals(_item2, tuple._item2); } int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) { var hash = comparer.GetHashCode(_item1); hash = (hash << 5) - hash + comparer.GetHashCode(_item2); return hash; } int IComparable.CompareTo(object obj) { return CompareTo(obj, Comparer.Default); } public override string ToString() { return string.Format(CultureInfo.InvariantCulture, "({0}, {1})", _item1, _item2); } private int CompareTo(object other, IComparer comparer) { if (other == null) { return 1; } var tuple = other as Tuple; if (tuple == null) { throw new ArgumentException("other"); } var result = comparer.Compare(_item1, tuple._item1); if (result == 0) { result = comparer.Compare(_item2, tuple._item2); } return result; } } } #endif