From 13e31c7430c444e919166f5fb5a2137fbcd991fa Mon Sep 17 00:00:00 2001 From: David Hall Date: Fri, 22 Feb 2019 14:27:45 -0700 Subject: [PATCH] Improved documentation and usability --- Core/Collections/VirtualDictionary.cs | 402 +++++++++++++++++++++------------- 1 file changed, 244 insertions(+), 158 deletions(-) diff --git a/Core/Collections/VirtualDictionary.cs b/Core/Collections/VirtualDictionary.cs index 7d9607a0..45212356 100644 --- a/Core/Collections/VirtualDictionary.cs +++ b/Core/Collections/VirtualDictionary.cs @@ -5,165 +5,13 @@ using System.Linq; namespace Vanara.Collections { - /// - /// A generic base class for providing a dictionary that gets and sets its values using virtual method calls. Useful for exposing lookups - /// into existing list environments like the file system, registry, service controller, etc. - /// - /// The type of keys in the dictionary. - /// The type of values in the dictionary. - public abstract class VirtualDictionary : IReadOnlyDictionary, IDictionary - { - /// Initializes a new instance of the class. - /// if set to true [read only]. - protected VirtualDictionary(bool readOnly) - { - IsReadOnly = readOnly; - } - - /// Gets the number of elements in the collection. - /// The number of elements in the collection. - public virtual int Count => Keys.Count; - - /// - public bool IsReadOnly { get; internal set; } - - /// - public abstract ICollection Keys { get; } - - /// - IEnumerable IReadOnlyDictionary.Keys => Keys; - - /// - public virtual ICollection Values => Keys.Select(k => this[k]).ToList(); - - /// - IEnumerable IReadOnlyDictionary.Values => Values; - - /// Gets the enumerated list of items. - /// The enumerated list of items. - protected IEnumerable> Items => - Keys.Select(k => new KeyValuePair(k, this[k])); - - /// Gets or sets the value with the specified key. - /// The value. - /// The key. - /// - public virtual TValue this[TKey key] - { - get => TryGetValue(key, out var value) ? value : default; - set => SetValue(key, value); - } - - /// - public void Add(TKey key, TValue value) => SetValue(key, value); - - /// - public void Add(KeyValuePair item) => Add(item.Key, item.Value); - - /// - public virtual void Clear() - { - foreach (var key in Keys.ToList()) - Remove(key); - } - - /// - public bool Contains(KeyValuePair item) => - ContainsKey(item.Key) && Equals(this[item.Key], item.Value); - - /// Determines whether the read-only dictionary contains an element that has the specified key. - /// The key to locate. - /// - /// if the read-only dictionary contains an element that has the specified key; otherwise, . - /// - public abstract bool ContainsKey(TKey key); - - /// - public virtual void CopyTo(KeyValuePair[] array, int arrayIndex) - { - var items = Items.ToArray(); - Array.Copy(items, 0, array, arrayIndex, items.Length); - } - - /// - public IEnumerator> GetEnumerator() => Items.GetEnumerator(); - - /// - public abstract bool Remove(TKey key); - - /// - public bool Remove(KeyValuePair item) => Contains(item) && Remove(item.Key); - - /// Gets the value that is associated with the specified key. - /// The key to locate. - /// - /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the - /// type of the parameter. This parameter is passed uninitialized. - /// - /// - /// if the object that implements the - /// interface contains an element that has the specified key; otherwise, . - /// - public abstract bool TryGetValue(TKey key, out TValue value); - - /// - /// Sets the value that is associated with the specified key. If the value for does not exist, this method - /// should create it. If the value does exist, this method should update it to match . - /// - /// The key for which to set the data. - /// The value to associate with the key. - protected abstract void SetValue(TKey key, TValue value); - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } - - /// - /// A generic base class for providing a read-only dictionary that gets its values using virtual method calls. Useful for exposing lookups - /// into existing list environments like the file system, registry, service controller, etc. - /// - /// The type of keys in the dictionary. - /// The type of values in the dictionary. - public abstract class VirtualReadOnlyDictionary : IReadOnlyDictionary - { - /// - public abstract IEnumerable Keys { get; } - - /// - public virtual int Count => Keys.Count(); - - /// - public virtual IEnumerable Values => Keys.Select(k => this[k]).ToList(); - - /// Gets the enumerated list of items. - /// The enumerated list of items. - protected IEnumerable> Items => - Keys.Select(k => new KeyValuePair(k, this[k])); - - /// - public virtual TValue this[TKey key] => TryGetValue(key, out var value) ? value : default; - - /// - public abstract bool ContainsKey(TKey key); - - /// - public IEnumerator> GetEnumerator() => Items.GetEnumerator(); - - /// - public abstract bool TryGetValue(TKey key, out TValue value); - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } - /// A generic class that creates a read-only dictionary from a list and getter function. - /// The type of the key. - /// The type of the value. + /// The type of keys in the dictionary. + /// The type of values in the dictionary. public class GenericVirtualReadOnlyDictionaryy : VirtualReadOnlyDictionary { - public delegate bool TryGetValueDelegate(TKey key, out TValue value); - private readonly TryGetValueDelegate getValFunc; + private readonly Func hasKeyFunc; /// Initializes a new instance of the class. @@ -180,15 +28,253 @@ namespace Vanara.Collections hasKeyFunc = hasKey ?? DefHasKey; } - /// + /// Delegate for the implementation of the method. + /// The key whose value to get. + /// + /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the + /// type of the parameter. This parameter is passed uninitialized. + /// + /// + /// if the contains an element with the key; otherwise, . + /// + public delegate bool TryGetValueDelegate(TKey key, out TValue value); + + /// Gets an enumerable collection that contains the keys in the read-only dictionary. + /// An enumerable collection that contains the keys in the read-only dictionary. + /// + /// The order of the keys in the enumerable collection is unspecified, but the implementation must guarantee that the keys are in the + /// same order as the corresponding values in the enumerable collection that is returned by the property. + /// public override IEnumerable Keys { get; } - /// + /// Determines whether the contains an element with the specified key. + /// The key to locate in the . + /// + /// if the contains an element with the key; otherwise, . + /// public override bool ContainsKey(TKey key) => hasKeyFunc(key); - /// + /// Gets the value associated with the specified key. + /// The key whose value to get. + /// + /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the + /// type of the parameter. This parameter is passed uninitialized. + /// + /// + /// if the contains an element with the key; otherwise, . + /// public override bool TryGetValue(TKey key, out TValue value) => getValFunc(key, out value); private bool DefHasKey(TKey k1) => Keys.Any(k2 => Equals(k1, k2)); } + + /// + /// A generic base class for providing a dictionary that gets and sets its values using virtual method calls. Useful for exposing lookups + /// into existing list environments like the file system, registry, service controller, etc. + /// + /// The type of keys in the dictionary. + /// The type of values in the dictionary. + public abstract class VirtualDictionary : IReadOnlyDictionary, IDictionary + { + /// Initializes a new instance of the class. + /// if set to true makes the collection read-only. + protected VirtualDictionary(bool readOnly) => IsReadOnly = readOnly; + + /// Gets a value indicating whether this instance is read only. + /// if this instance is read only; otherwise, . + public bool IsReadOnly { get; internal set; } + + /// Gets an containing the keys of the . + /// An containing the keys of the object that implements . + public abstract ICollection Keys { get; } + + /// Gets an containing the values in the . + /// An containing the values in the object that implements . + /// + /// The order of the keys in the enumerable collection is unspecified, but the implementation must guarantee that the values are in + /// the same order as the corresponding keys in the enumerable collection that is returned by the property. + /// + public virtual ICollection Values => Keys.Select(k => this[k]).ToList(); + + /// Gets the number of elements contained in the . + /// The number of elements contained in the . + public virtual int Count => Keys.Count; + + /// Gets an enumerable collection that contains the keys in the read-only dictionary. + /// An enumerable collection that contains the keys in the read-only dictionary. + /// + /// The order of the keys in the enumerable collection is unspecified, but the implementation must guarantee that the keys are in the + /// same order as the corresponding values in the enumerable collection that is returned by the property. + /// + IEnumerable IReadOnlyDictionary.Keys => Keys; + + /// Gets an containing the values in the . + /// An containing the values in the object that implements . + IEnumerable IReadOnlyDictionary.Values => Values; + + /// Gets the enumerated list of items. + /// The enumerated list of items. + protected IEnumerable> Items => + Keys.Select(k => new KeyValuePair(k, this[k])); + + /// Gets or sets the with the specified key. + /// The element with the specified key. + /// The key of the element to get or set. + public virtual TValue this[TKey key] + { + get => TryGetValue(key, out var value) ? value : default; + set => SetValue(key, value); + } + + /// Removes all items from the . + public virtual void Clear() + { + foreach (var key in Keys.ToList()) + Remove(key); + } + + /// Determines whether the contains an element with the specified key. + /// The key to locate in the . + /// + /// if the contains an element with the key; otherwise, . + /// + public virtual bool ContainsKey(TKey key) => Keys.Contains(key); + + /// + /// Copies the elements of the to an , starting at a + /// particular index. + /// + /// + /// The one-dimensional that is the destination of the elements copied from + /// . The must have zero-based indexing. + /// + /// The zero-based index in at which copying begins. + public virtual void CopyTo(KeyValuePair[] array, int arrayIndex) + { + var items = Items.ToArray(); + Array.Copy(items, 0, array, arrayIndex, items.Length); + } + + /// Returns an enumerator that iterates through the collection. + /// An enumerator that can be used to iterate through the collection. + public IEnumerator> GetEnumerator() => Items.GetEnumerator(); + + /// Removes the element with the specified key from the . + /// The key of the element to remove. + /// + /// if the element is successfully removed; otherwise, . This method also returns false + /// if key was not found in the original . + /// + public virtual bool Remove(TKey key) => throw new NotSupportedException(); + + /// Gets the value associated with the specified key. + /// The key whose value to get. + /// + /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the + /// type of the parameter. This parameter is passed uninitialized. + /// + /// + /// if the contains an element with the key; otherwise, . + /// + public abstract bool TryGetValue(TKey key, out TValue value); + + /// Adds an item to the . + /// The object to add to the . + void IDictionary.Add(TKey key, TValue value) => SetValue(key, value); + + /// Adds an element with the provided key and value to the . + /// The object to use as the key of the element to add. + /// The object to use as the value of the element to add. + void ICollection>.Add(KeyValuePair item) => SetValue(item.Key, item.Value); + + /// Determines whether contains a specific value. + /// The object to locate in the . + /// + /// if item is found in the ; otherwise, . + /// + bool ICollection>.Contains(KeyValuePair item) => + ContainsKey(item.Key) && Equals(this[item.Key], item.Value); + + /// Returns an enumerator that iterates through a collection. + /// An object that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// Removes the first occurrence of a specific object from the . + /// The object to remove from the . + /// + /// if was successfully removed; otherwise, . This method also + /// returns false if was not found in the original . + /// + bool ICollection>.Remove(KeyValuePair item) => ((ICollection>)this).Contains(item) && Remove(item.Key); + + /// + /// Sets the value that is associated with the specified key. If the value for does not exist, this method + /// should create it. If the value does exist, this method should update it to match . + /// + /// The key for which to set the data. + /// The value to associate with the key. + protected virtual void SetValue(TKey key, TValue value) => throw new NotSupportedException(); + } + + /// + /// A generic base class for providing a read-only dictionary that gets its values using virtual method calls. Useful for exposing + /// lookups into existing list environments like the file system, registry, service controller, etc. + /// + /// The type of keys in the dictionary. + /// The type of values in the dictionary. + public abstract class VirtualReadOnlyDictionary : IReadOnlyDictionary + { + /// Gets an enumerable collection that contains the keys in the read-only dictionary. + /// An enumerable collection that contains the keys in the read-only dictionary. + /// + /// The order of the keys in the enumerable collection is unspecified, but the implementation must guarantee that the keys are in the + /// same order as the corresponding values in the enumerable collection that is returned by the property. + /// + public abstract IEnumerable Keys { get; } + + /// + /// Gets an containing the values in the . + /// An containing the values in the object that implements . + public virtual IEnumerable Values => Keys.Select(k => this[k]).ToList(); + + /// Gets the number of elements contained in the . + /// The number of elements contained in the . + public virtual int Count => Keys.Count(); + + /// Gets the enumerated list of items. + /// The enumerated list of items. + protected IEnumerable> Items => + Keys.Select(k => new KeyValuePair(k, this[k])); + + /// Gets the with the specified key. + /// The element with the specified key. + /// The key of the element to get. + public virtual TValue this[TKey key] => TryGetValue(key, out var value) ? value : default; + + /// Determines whether the contains an element with the specified key. + /// The key to locate in the . + /// + /// if the contains an element with the key; otherwise, . + /// + public abstract bool ContainsKey(TKey key); + + /// Returns an enumerator that iterates through the collection. + /// An enumerator that can be used to iterate through the collection. + public IEnumerator> GetEnumerator() => Items.GetEnumerator(); + + /// Gets the value associated with the specified key. + /// The key whose value to get. + /// + /// When this method returns, the value associated with the specified key, if the key is found; otherwise, the default value for the + /// type of the parameter. This parameter is passed uninitialized. + /// + /// + /// if the contains an element with the key; otherwise, . + /// + public abstract bool TryGetValue(TKey key, out TValue value); + + /// Returns an enumerator that iterates through a collection. + /// An object that can be used to iterate through the collection. + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } } \ No newline at end of file