/// <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()))); }
public int GetHashCode(KeyAndValues obj) { return(CollectionUtil.GetHashCode(obj.Key, keyEqualityComparer)); }
public int GetHashCode(KeyValuePair <TKey, TValue> obj) { return(CollectionUtil.GetHashCode(obj.Key, keyEqualityComparer)); }