コード例 #1
0
        private HashCodeHelper HashReadOnlyDictionary <TKey, TValue>(
            IReadOnlyDictionary <TKey, TValue> dictionary)
        {
            HashCodeHelper result = this;

            if (dictionary == null)
            {
                // We cannot just use the current hash code value as is.
                // We have to hash null and thus change the current hash code.
                // Consider the following collection of dictionaries:
                // { { "a": 1 }, { "b": 2 } }
                // { { "a": 1 }, null, { "b": 2 } }
                // They would result in the same hash code if we didn't hash null.
                result = result.Hash <object>(null);
            }
            else
            {
                result = result.HashUnorderedCollection(dictionary.Keys);

                // Is there a comparer for the keys?
                if (!TypeExtensions.HasWorkingDefaultComparer <TKey>())
                {
                    // There is no comparer for the keys and thus we cannot sort the key/value pairs.
                    // The best we can do is hash the count, which will ensure
                    // that two dictionaries, having a different count, will
                    // not return the same hash code.
                    result = result.Hash(dictionary.Count);
                }
                else
                {
                    // The keys can be sorted.  Sort the key/value pairs by the keys
                    // and then hash the key collection and the value collection,
                    // treating them as ordered collections.
                    var keyValuePairsInOrder = dictionary.OrderBy(_ => _.Key).ToList();

                    result = result.HashOrderedCollection(keyValuePairsInOrder.Select(_ => _.Key));

                    result = result.HashOrderedCollection(keyValuePairsInOrder.Select(_ => _.Value));
                }
            }

            return(result);
        }
コード例 #2
0
        private HashCodeHelper HashUnorderedCollection <TElement>(
            IEnumerable <TElement> collection)
        {
            HashCodeHelper result = this;

            if (collection == null)
            {
                // We cannot just use the current hash code value as is.
                // We have to hash null and thus change the current hash code.
                // Consider the following collection of collections:
                // { { 1, 2 }, {3, 4} }
                // { { 1, 2 }, null, {3, 4}  }
                // They would result in the same hash code if we didn't hash null.
                result = result.Hash <object>(null);
            }
            else
            {
                // Is there a comparer for the element type?
                // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                if (!TypeExtensions.HasWorkingDefaultComparer <TElement>())
                {
                    // There is no comparer and thus we cannot sort the elements.
                    // The best we can do is hash the element count, which will ensure
                    // that two unordered collections, having a different count, will
                    // not return the same hash code.
                    result = result.Hash(collection.Count());
                }
                else
                {
                    // There is a comparer; sort the collection and then treat
                    // it as an ordered collection and hash that.  This ensures that
                    // two unordered collections that are equal but having a different
                    // order will result in the same hash code.
                    result = result.HashOrderedCollection(collection.OrderBy(_ => _));
                }
            }

            return(result);
        }