// -----------------------------------------------------------------------
//
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// -----------------------------------------------------------------------
namespace Lucene.Net.Support
{
using System;
using System.Collections.Generic;
#if !SILVERLIGHT
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(PREFIX + "DictionaryDebugView`2" + SUFFIX)]
#endif
///
/// The abstract type that helps to construct specialized dictionaries.
///
/// The type of the keys in the dictionary.
/// The type of the values in the dictionary.
///
///
///
/// C# File:
/// src/Lucene.Net/Support/BaseDictionaryOfTKeyTValue.cs
///
///
///
/// C# Tests:
/// test/Lucene.Net.Test/Support/WeakDictionaryOfTKeyTValueTest.cs
///
///
///
///
public abstract class BaseDictionary : IDictionary
{
private KeyCollection keys;
private ValueCollection values;
///
/// Gets the number of key pair values stored in the dictionary.
///
public abstract int Count { get; }
///
/// Gets a value indicating whether this instance is read only.
///
///
/// true if this instance is read only; otherwise, false.
///
public bool IsReadOnly
{
get { return false; }
}
///
/// Gets the keys.
///
/// The keys.
public ICollection Keys
{
get { return this.keys ?? (this.keys = new KeyCollection(this)); }
}
///
/// Gets the values.
///
/// The values.
public ICollection Values
{
get { return this.values ?? (this.values = new ValueCollection(this)); }
}
///
/// Gets or sets the with the specified key.
///
/// The key mapped to a value.
///
/// The instance that is mapped to the
///
///
/// Thrown when the specified can not be found.
///
public TValue this[TKey key]
{
get
{
TValue value;
if (!this.TryGetValue(key, out value))
throw new KeyNotFoundException();
return value;
}
set
{
this.SetValue(key, value);
}
}
///
/// Adds the specified key and value to the dictionary.
///
/// The key of the element to add.
/// The value of the element to add.
public abstract void Add(TKey key, TValue value);
///
/// Adds the specified item.
///
/// The item.
public void Add(KeyValuePair item)
{
this.Add(item.Key, item.Value);
}
///
/// Removes all the key pair values from the dictionary and resets the count.
///
public abstract void Clear();
///
/// Determines whether [contains] [the specified item].
///
/// The item.
///
/// true if [contains] [the specified item]; otherwise, false.
///
public bool Contains(KeyValuePair item)
{
TValue value;
return this.TryGetValue(item.Key, out value) &&
EqualityComparer.Default.Equals(value, item.Value);
}
///
/// Determines whether the contains the specified key.
///
/// The key to locate in the dictionary.
///
///
/// This method approaches an O(1) operation.
///
///
/// true if the was found, otherwise false
/// Throw when the is null.
public abstract bool ContainsKey(TKey key);
///
/// Copies to.
///
/// The array.
/// Index of the array.
public void CopyTo(KeyValuePair[] array, int arrayIndex)
{
Copy(this, array, arrayIndex);
}
///
/// Returns an enumerator that iterates through the .
///
/// A of structure for the Dictionary.
public abstract IEnumerator> GetEnumerator();
///
/// Removes the specified key from .
///
/// The key of the element to remove.
///
/// true if the element was successfully found and removed, otherwise false
///
public abstract bool Remove(TKey key);
///
/// Removes the specified item.
///
/// The item.
/// true if element was found and successfully removed; otherwise, false.
public bool Remove(KeyValuePair item)
{
if (!this.Contains(item))
return false;
return this.Remove(item.Key);
}
///
/// Attempts to the get value of the associated key.
///
///
///
/// This method combines the functionality of the ContainsKey method and the Item property.
///
///
/// If the key is not found, then the value parameter gets the appropriate default value
/// for the value type TValue; for example, 0 (zero) for integer types, false for Boolean
/// types, and null for reference types.
///
///
/// Use the TryGetValue method if your code frequently attempts to access keys that are not
/// in the dictionary. Using this method is more efficient than catching the
/// KeyNotFoundException thrown by the Item property.
///
///
/// This method approaches an O(1) operation.
///
///
/// The key.
/// The value.
///
/// trueif the contains an element with the
/// specified key; otherwise, false.
///
public abstract bool TryGetValue(TKey key, out TValue value);
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
///
/// Sets the value.
///
/// The key.
/// The value.
protected abstract void SetValue(TKey key, TValue value);
private static void Copy(ICollection source, T[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException("array");
if (arrayIndex < 0 || arrayIndex > array.Length)
throw new ArgumentOutOfRangeException("arrayIndex");
if ((array.Length - arrayIndex) < source.Count)
throw new ArgumentException("Destination array is not large enough. Check array.Length and arrayIndex.");
foreach (T item in source)
array[arrayIndex++] = item;
}
///
/// The base class for providing the and
/// collections.
///
/// The type.
private abstract class Collection : ICollection
{
protected readonly IDictionary Dictionary;
///
/// Initializes a new instance of the class.
///
/// The dictionary.
protected Collection(IDictionary dictionary)
{
this.Dictionary = dictionary;
}
///
/// Gets the count.
///
/// The count.
public int Count
{
get { return this.Dictionary.Count; }
}
///
/// Gets a value indicating whether this instance is read only.
///
///
/// true if this instance is read only; otherwise, false.
///
public bool IsReadOnly
{
get { return true; }
}
///
/// Adds the specified item.
///
/// The item.
public void Add(T item)
{
throw new NotSupportedException("Collection is read-only.");
}
///
/// Clears this instance.
///
public void Clear()
{
throw new NotSupportedException("Collection is read-only.");
}
///
/// Determines whether [contains] [the specified item].
///
/// The item.
///
/// true if [contains] [the specified item]; otherwise, false.
///
public virtual bool Contains(T item)
{
foreach (T element in this)
if (EqualityComparer.Default.Equals(element, item))
return true;
return false;
}
///
/// Copies to.
///
/// The array.
/// Index of the array.
public void CopyTo(T[] array, int arrayIndex)
{
Copy(this, array, arrayIndex);
}
///
/// Returns an enumerator that iterates through the collection.
///
/// An of that can be used to iterate through the collection.
public IEnumerator GetEnumerator()
{
foreach (KeyValuePair pair in this.Dictionary)
yield return this.GetItem(pair);
}
///
/// Removes the specified item.
///
/// The item.
///
/// true if the item was successfully removed; otherwise, false.
///
///
/// Throw when this method is called. This collection is read only.
///
public bool Remove(T item)
{
throw new NotSupportedException("Collection is read-only.");
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
///
/// Gets the item.
///
/// The pair.
/// an instance of .
protected abstract T GetItem(KeyValuePair pair);
}
#if !SILVERLIGHT
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(PREFIX + "DictionaryKeyCollectionDebugView`2" + SUFFIX)]
#endif
///
/// The collection of dictionary keys.
///
private class KeyCollection : Collection
{
///
/// Initializes a new instance of the class.
///
/// The dictionary.
public KeyCollection(IDictionary dictionary)
: base(dictionary)
{
}
///
/// Determines whether [contains] [the specified item].
///
/// The item.
///
/// true if [contains] [the specified item]; otherwise, false.
///
public override bool Contains(TKey item)
{
return this.Dictionary.ContainsKey(item);
}
///
/// Gets the item.
///
/// The pair.
///
/// An instance of .
///
protected override TKey GetItem(KeyValuePair pair)
{
return pair.Key;
}
}
#if !SILVERLIGHT
[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(PREFIX + "DictionaryValueCollectionDebugView`2" + SUFFIX)]
#endif
///
/// The collection of values from the dictionary.
///
private class ValueCollection : Collection
{
///
/// Initializes a new instance of the class.
///
/// The dictionary.
public ValueCollection(IDictionary dictionary)
: base(dictionary)
{
}
///
/// Gets the item.
///
/// The pair.
///
/// An instance of .
///
protected override TValue GetItem(KeyValuePair pair)
{
return pair.Value;
}
}
}
}