示例#1
0
        /// <summary>
        /// Gets the hashcode of a single object. If the object is an enumerable it will make a hashcode of the enumeration.
        /// </summary>
        /// <param name="o">Object to make the hashcode for.</param>
        /// <returns>A hashcode.</returns>
        public static int GetHashCodeForSingleObject(object o)
        {
            if (ReferenceEquals(o, null))
            {
                return(0);
            }

            var oEnumerable = o as IEnumerable;

            if (oEnumerable == null)
            {
                // check for the special case of KeyValuePair (items of a dictionary)
                var kvp = KeyValuePairMethods.TryExtractKeyValuePair(o);
                if (kvp != null)
                {
                    return(GetHashCodeFor(kvp.Item1, kvp.Item2));
                }

                return(o.GetHashCode());
            }

            // make a hash of the items if it is an enumerable
            var oEnum = oEnumerable.GetEnumerator();

            var list = new List <object>();

            while (oEnum.MoveNext())
            {
                list.Add(oEnum.Current);
            }

            return(GetHashCodeFor(list.ToArray()));
        }
        public static KeyValuePairMethods GetForType(Type type)
        {
            if (!type.IsGenericType || (StripGenericFromFullName(type.FullName) != ClassFullName))
            {
                return(null);
            }

            // TODO: this probably could be more performant by using a concurrent dictionary
            lock (KeyValuePairMethodsDictionaryLock) {
                KeyValuePairMethods kvpm;
                if (!KeyValuePairMethodsDictionary.TryGetValue(type, out kvpm))
                {
                    kvpm = new KeyValuePairMethods(type);
                    KeyValuePairMethodsDictionary.Add(type, kvpm);
                }
                return(kvpm);
            }
        }
示例#3
0
        /// <summary>
        /// Returns the string representation of an object, null if null or [items] if a collection.
        /// </summary>
        /// <param name="o"></param>
        /// <returns>The string representation.</returns>
        public static string ToStringForSingleObject(object o)
        {
            if (ReferenceEquals(o, null))
            {
                return("null");
            }

            var oEnumerable = o as IEnumerable;

            if (oEnumerable == null)
            {
                // check for the special case of KeyValuePair (items of a dictionary)
                var kvp = KeyValuePairMethods.TryExtractKeyValuePair(o);
                if (kvp != null)
                {
                    return("(" + ToStringForSingleObject(kvp.Item1) + ", " + ToStringForSingleObject(kvp.Item2) + ")");
                }

                return(o.ToString());
            }

            // make a list of the items if it is an enumerable
            var oEnum = oEnumerable.GetEnumerator();

            var list = new List <object>();

            while (oEnum.MoveNext())
            {
                list.Add(oEnum.Current);
            }

            var sb = new StringBuilder();

            sb.Append("[ ");
            // TODO: this could be optimized by not using select and using the append on each object instead
            sb.Append(string.Join(", ", list.Select(ToStringForSingleObject)));
            sb.Append(" ]");
            return(sb.ToString());
        }
示例#4
0
        /// <summary>
        /// Check if two objects are equal.
        /// </summary>
        /// <typeparam name="T">Object type.</typeparam>
        /// <param name="a">First object.</param>
        /// <param name="b">Second object.</param>
        /// <returns>true if they are equal, false otherwise.</returns>
        public static bool AreEqual <T>(T a, T b)
        {
            bool aIsNull = ReferenceEquals(a, null), bIsNull = ReferenceEquals(b, null);

            if (aIsNull && bIsNull)
            {
                return(true);
            }
            if (aIsNull || bIsNull)
            {
                return(false);
            }
            var equals = a.Equals(b);

            if (equals)
            {
                return(true);
            }

            // check for the special case of KeyValuePair (items of a dictionary)
            var aKvp = KeyValuePairMethods.TryExtractKeyValuePair(a);

            if (aKvp != null)
            {
                var bKvp = KeyValuePairMethods.TryExtractKeyValuePair(b);
                return(AreEqual(aKvp.Item1, bKvp.Item1) && AreEqual(aKvp.Item2, bKvp.Item2));
            }

            // one extra check for enumerables

            // first a fastcheck for collection size
            var aCollection = a as ICollection;
            var bCollection = b as ICollection;

            if ((aCollection != null) && (bCollection != null))
            {
                if (aCollection.Count != bCollection.Count)
                {
                    return(false);
                }
            }

            var aEnumerable = a as IEnumerable;
            var bEnumerable = b as IEnumerable;

            if ((aEnumerable == null) || (bEnumerable == null))
            {
                return(false);
            }

            var aEnum = aEnumerable.GetEnumerator();
            var bEnum = bEnumerable.GetEnumerator();

            while (aEnum.MoveNext())
            {
                if (!bEnum.MoveNext())
                {
                    return(false);
                }
                object aCurrent = aEnum.Current, bCurrent = bEnum.Current;
                if (!AreEqual(aCurrent, bCurrent))
                {
                    return(false);
                }
            }

            // all items so far are the same, but does b have one more?
            return(!bEnum.MoveNext());
        }