/// <summary>
        /// Remove any association in the dictionary with the specified key.
        /// </summary>
        /// <param name="key">The key of the association to remove.</param>
        /// <exception cref="ArgumentNullException">Gets raised when the <paramref name="key"/> parameter is null.</exception>
        public void Remove(TKey key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            var item = new ConcurrentWeakDictionaryStrongValuesKey <TKey>(GetHashCode(key), key);
            ConcurrentWeakDictionaryStrongValuesItem <TValue> oldItem;

            base.RemoveItem(ref item, out oldItem);
        }
        /// <summary>
        /// Try to find an association with the specified key, return it and remove the association from the dictionary.
        /// </summary>
        /// <param name="key">The key to find the association with.</param>
        /// <param name="value">An out reference to assign the value of the found association to. If no association can be found the reference will be set to default(<typeparamref name="TValue"/>).</param>
        /// <returns>True if an association can be found; otherwise false.</returns>
        /// <exception cref="ArgumentNullException">Gets raised when the <paramref name="key"/> parameter is null.</exception>
        public bool TryPopValue(TKey key, out TValue value)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            var item = new ConcurrentWeakDictionaryStrongValuesKey <TKey>(GetHashCode(key), key);
            ConcurrentWeakDictionaryStrongValuesItem <TValue> oldItem;

            if (base.RemoveItem(ref item, out oldItem))
            {
                value = oldItem._Value;
                return(true);
            }

            value = default(TValue);
            return(false);
        }
        /// <summary>
        /// Compares a storeable item to a search key. Should return true if they match.
        /// </summary>
        /// <param name="item">Reference to the storeable item to compare.</param>
        /// <param name="key">Reference to the search key to compare.</param>
        /// <returns>True if the storeable item and search key match; false otherwise.</returns>
        internal protected override bool ItemEqualsKey(ref ConcurrentWeakDictionaryStrongValuesItem <TValue> item, ref ConcurrentWeakDictionaryStrongValuesKey <TKey> key)
        {
            var key1 = (TKey)item._Key.Target;

            return(_Comparer.Equals(key1, key._Key));
        }
 /// <summary>
 /// Get a hashcode for given search key.
 /// </summary>
 /// <param name="key">Reference to the key to get a hash value for.</param>
 /// <returns>The hash value as an <see cref="UInt32"/>.</returns>
 /// <remarks>
 /// The hash returned should be properly randomized hash. The standard GetItemHashCode methods are usually not good enough.
 /// A storeable item and a matching search key should return the same hash code.
 /// So the statement <code>ItemEqualsItem(storeableItem, searchKey) ? GetItemHashCode(storeableItem) == GetItemHashCode(searchKey) : true </code> should always be true;
 /// </remarks>
 internal protected override UInt32 GetKeyHashCode(ref ConcurrentWeakDictionaryStrongValuesKey <TKey> key)
 {
     return(key._Hash);
 }