示例#1
0
        /// <summary>
        /// Makes a deep clone of this dictionary. A new dictionary is created with a clone of
        /// each entry of this dictionary, by calling ICloneable.Clone on each element. If TKey or TValue is
        /// a value type, then each element is copied as if by simple assignment.
        /// </summary>
        /// <remarks><para>If TKey or TValue is a reference type, it must implement
        /// ICloneable. Otherwise, an InvalidOperationException is thrown.</para>
        /// <para>Cloning the dictionary takes time O(N log N), where N is the number of key-value pairs in the dictionary.</para></remarks>
        /// <returns>The cloned dictionary.</returns>
        /// <exception cref="InvalidOperationException">TKey or TValue is a reference type that does not implement ICloneable.</exception>
        public MultiDictionary <TKey, TValue> CloneContents()
        {
            bool keyIsValueType, valueIsValueType;

            // Make sure that TKey and TValue can be cloned.
            if (!CollectionUtil.IsCloneableType(typeof(TKey), out keyIsValueType))
            {
                NonCloneableType(typeof(TKey));
            }

            if (!CollectionUtil.IsCloneableType(typeof(TValue), out valueIsValueType))
            {
                NonCloneableType(typeof(TValue));
            }

            // It's tempting to do a more efficient cloning, utilizing the hash.Clone() method. However, we can't know that
            // the cloned version of the key has the same hash value.

            MultiDictionary <TKey, TValue> newDict = new MultiDictionary <TKey, TValue>(allowDuplicateValues, keyEqualityComparer, valueEqualityComparer);

            foreach (KeyAndValues item in hash)
            {
                // Clone the key and values parts. Value types can be cloned
                // by just copying them, otherwise, ICloneable is used.
                TKey     keyClone;
                TValue[] valuesClone;

                if (keyIsValueType)
                {
                    keyClone = item.Key;
                }
                else
                {
                    if (item.Key == null)
                    {
                        keyClone = default(TKey);  // Really null, because we know TKey isn't a value type.
                    }
                    else
                    {
                        keyClone = (TKey)(((ICloneable)item.Key).Clone());
                    }
                }

                valuesClone = new TValue[item.Count];
                if (valueIsValueType)
                {
                    Array.Copy(item.Values, valuesClone, item.Count);
                }
                else
                {
                    for (int i = 0; i < item.Count; ++i)
                    {
                        if (item.Values[i] == null)
                        {
                            valuesClone[i] = default(TValue);   // Really null, because we know TKey isn't a value type.
                        }
                        else
                        {
                            valuesClone[i] = (TValue)(((ICloneable)item.Values[i]).Clone());
                        }
                    }
                }

                newDict.AddMany(keyClone, valuesClone);
            }

            return(newDict);
        }
 /// <summary>
 /// Throws an NotSupportedException stating that this collection cannot be modified.
 /// </summary>
 private void MethodModifiesCollection()
 {
     throw new NotSupportedException(string.Format(Strings.CannotModifyCollection, CollectionUtil.SimpleClassName(this.GetType())));
 }
示例#3
0
 public int GetHashCode(KeyAndValues obj)
 {
     return(CollectionUtil.GetHashCode(obj.Key, keyEqualityComparer));
 }
示例#4
0
 public int GetHashCode(KeyValuePair <TKey, TValue> obj)
 {
     return(CollectionUtil.GetHashCode(obj.Key, keyEqualityComparer));
 }