/* Copyright 2009 David Schmitt (http://dasz.at/) This program is licensed under the GNU Lesser General Public License (LGPL). You should have received a copy of the license along with the source code. If not, an online copy of the license can be found at http://www.gnu.org/copyleft/lesser.html. */ using System; using NGenerics.Util; namespace NGenerics.DataStructures.General { /// /// An immutable class representing a pair of values with value semantics. /// /// The type of object the pair contains. #if (!SILVERLIGHT) [Serializable] #endif public class Pair { #region Globals private readonly T a; private readonly T b; #endregion #region Construction /// The first value. /// The other value. public Pair(T a, T b) { this.a = a; this.b = b; } #endregion #region Public Members /// /// Gets the A-half of this . /// /// The A-half. public T A { get { return this.a; } } /// /// Gets the B-half of this . /// /// The B-half. public T B { get { return this.b; } } #endregion #region Object Overrides /// /// Creates a user-readable string representation of this Pair. /// /// A user-readable string. public override string ToString() { return String.Format("({0}, {1})", this.a, this.b); } /// /// Compares this Pair to another Pair, based on their parts. /// /// The object to compare to. /// If the is a pair of the same objects as this pair, returns true. Returns false otherwise. public override bool Equals(object obj) { // shortcut reference equality if (Object.ReferenceEquals(this, obj)) { return true; } var other = obj as Pair; if (other == null) { return false; } return Object.Equals(this.a, other.a) && Object.Equals(this.b, other.b); } /// /// Calculates a hash code from this pair's constituents. /// /// A hashcode suitable for use in Hastables and similar structures. public override int GetHashCode() { return (Object.ReferenceEquals(this.a, null) ? 0 : this.a.GetHashCode()) ^ (Object.ReferenceEquals(this.b, null) ? 0 : this.b.GetHashCode()); } /// /// Compares the two Pairs based on their constituents. /// /// The first element to compare. /// The second element to compare. /// true, if both pairs have the same contents; false,otherwise. public static bool operator ==(Pair left, Pair right) { // shortcut reference equality if (Object.ReferenceEquals(left, right)) { return true; } return Object.ReferenceEquals(left, null) || left.Equals(right); } /// /// Compares the two Pairs based on their constituents. /// /// The first element to compare. /// The second element to compare. /// false, if both pairs have the same contents; true,otherwise. public static bool operator !=(Pair left, Pair right) { return !(left == right); } #endregion } /// /// A few utility methods that do not need access to the private state of a . /// public static class PairExtensions { /// /// Creates a new with A and B switched. /// /// The type contained in the . /// The pair whose constituents are used. May not be null. /// public static Pair Reverse(this Pair self) { Guard.ArgumentNotNull(self, "self"); if (Object.Equals(self.A, self.B)) { return self; } else { return new Pair(self.B, self.A); } } public static System.Collections.Generic.KeyValuePair ToKeyValuePair(this Pair self) { return new System.Collections.Generic.KeyValuePair(self.A, self.B); } } }