Example #1
0
        /// <summary>
        /// Structural equality testing. Objects are equal if they are of the same type
        /// and if each field (given by the enumeration <see cref="FieldValues" />) is equal
        /// for the two values.
        /// </summary>
        /// <param name="obj">The value to compare to this value</param>
        /// <returns>True if the values are equal, false otherwise.</returns>
        public override bool Equals(object /*?*/ obj)
        {
            CompoundValue other = obj as CompoundValue;

            if ((object)other == null)
            {
                return(false);
            }
            if ((object)this == obj)
            {
                return(true);
            }
            if (this.GetType() != obj.GetType())
            {
                return(false);
            }

            IEnumerator <IComparable> fields1 = this.FieldValues().GetEnumerator();
            IEnumerator <IComparable> fields2 = other.FieldValues().GetEnumerator();

            while (true)
            {
                bool hasNext1 = fields1.MoveNext();
                bool hasNext2 = fields2.MoveNext();
                if (hasNext1 ^ hasNext2)
                {
                    return(false);                     // differing lengths
                }
                if (!hasNext1)
                {
                    return(true);
                }
                if (!Object.Equals(fields1.Current, fields2.Current))
                {
                    return(false);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Term order. Comparision is based on type and recursively on fields.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns>-1 if less than, 0 if equal, 1 if greater than</returns>
        /// <exception cref="System.ArgumentException">Thrown if <paramref name="obj"/> is nonnull but is not an <c>CompoundValue</c>.</exception>
        public override int CompareTo(object /*?*/ obj)
        //^ requires obj != null ==> obj is IComparable;
        //^ ensures result == 0 <==> Object.Equals(this, obj);
        //^ ensures result == -1 || result == 0 || result == 1;
        {
            // Case 1: other obj is null
            if (obj == null)
            {
                return(1);                // nonnull is bigger than null
            }
            CompoundValue other = obj as CompoundValue;

            if ((object)other == null)
            {
                throw new ArgumentException(MessageStrings.LocalizedFormat(MessageStrings.CompoundValueRequired, obj.GetType().ToString()));
            }


            // Case 2: types aren't the same, do type comparison in dictionary order
            Type t1 = this.GetType();
            Type t2 = obj.GetType();

            if (t1 != t2)
            {
                return(t1.ToString().CompareTo(t2.ToString()));
            }

            // Case 3: types are the same, look for first field that is not equal
            IEnumerator <IComparable> fields1 = this.FieldValues().GetEnumerator();
            IEnumerator <IComparable> fields2 = other.FieldValues().GetEnumerator();

            while (true)
            {
                bool hasNext1 = fields1.MoveNext();
                bool hasNext2 = fields2.MoveNext();
                if (hasNext1 & !hasNext2)
                {
                    return(1);                       // longer comes after shorter
                }
                if (!hasNext1 & hasNext2)
                {
                    return(-1);                      // shorter comes before longer
                }
                if (!hasNext1)
                {
                    return(0);                       // items are equal
                }
                IComparable c1 = fields1.Current as IComparable;
                IComparable c2 = fields2.Current as IComparable;
                if (fields1.Current != null && c1 == null)
                {
                    throw new ArgumentException(MessageStrings.LocalizedFormat(MessageStrings.ComparableTypeRequired, fields1.Current.GetType().ToString()));
                }
                if (fields2.Current != null && c2 == null)
                {
                    throw new ArgumentException(MessageStrings.LocalizedFormat(MessageStrings.ComparableTypeRequired, fields2.Current.GetType().ToString()));
                }
                int fieldCompare = HashAlgorithms.CompareValues(c1, c2);
                if (fieldCompare != 0)
                {
                    return(fieldCompare);
                }
            }
        }