/// <summary> /// This performs a "width first" search for the specified key. /// That is, it first looks in the Primary dictionary, /// then in the defaults, then does the same in each of the parents (from newest to oldest), /// This should NOT be used without a clear understanding that a default may be /// returned before all ancestors have been searched for a primary setting! /// If a "shallow" search is required, call "Shallow().TryGetAny()" instead. /// </summary> /// <param name="key">The key that will be searched.</param> /// <param name="value">The out value of the entry if one is found.</param> /// <returns>A boolean indicating if the specified key and associated value were found.</returns> public bool TryGetAny(TKey key, out TValue value) { lock (_syncRoot) { // finding it at the top-level means that we are done if (_localEntries.TryGetValue(key, out value)) { return(true); } // if all esle fails, try to return a default if it exists // Note that here you may end up getting a default before each parent branch has been queried! if (LocalDefaults.TryGetValue(key, out value)) { return(true); } // check each parent from newest to oldest // Note that here you may get a default before deeper ancestors are queried! for (var x = Parents.Count - 1; x >= 0; x--) { if (Parents[x].TryGetAny(key, out value)) { return(true); } } return(false); } }
/// <summary> /// This removes a default entry matching the specified key "shallowly". /// That is, it only removes it from the top-level Defaults dictionary (parent defaults are unaffected). /// Note that this is just a convenience, since the method could be called directly on Defaults. /// </summary> /// <remarks>Traking info is also removed.</remarks> /// <param name="key">The key that uniquely identifies the default entry of interest.</param> /// <returns>A boolean indicating if any default entries matching the key were found and removed.</returns> public bool RemoveLocalDefault(TKey key) { lock (_syncRoot) { return(LocalDefaults.Remove(key)); // Tracking info is also removed. } }
/// <summary> /// This adds a key/value pair "shallowly". /// That is, it only adds it to the top-level dictionary. /// The parents and defaults, if they exist, are unaffected. /// Note that this is just a convenience, since the method could also be called directly on the Primary dictionary. /// </summary> /// <param name="key"></param> /// <param name="value"></param> public void AddDefault(TKey key, TValue value) { lock (_syncRoot) { LocalDefaults.Add(key, value); } }
/// <summary> /// This constructor accepts an enumerable of initial properties for loading into the local dictionary, /// and another enumerable of default properties for loading into the "Defaults" dictionary. /// </summary> public FileDictionaryTree(string name, string fullName, IEnumerable <KeyValuePair <string, string> > initialProperties, IEnumerable <KeyValuePair <string, string> > defaultProperties) : this(name, fullName, initialProperties) { foreach (var pair in defaultProperties) { LocalDefaults.Add(pair.Key, pair.Value); } }
/// <summary> /// This clear all items from the entire data structure. /// That is, it first clears all items in the top-level dictionary, /// then it clears each of the parents, and finally it clears the defaults, if they exist. /// </summary> public void ClearDeeply() { lock (_syncRoot) { _localEntries.Clear(); foreach (var parent in Parents) { parent.ClearDeeply(); } if (LocalDefaults != null) { LocalDefaults.Clear(); } } }
/// <summary> /// This performs a "deep" search for the specified default key. /// That is, the Defaults dictionary, /// and the Defaults dictionaries of all ancestors will be searched. /// If a "shallow" search is required, call "Shallow().ContainsDefaultKey()" /// or directly call Defaults.ContainsKey() instead. /// </summary> /// <param name="key">The key that will be searched.</param> /// <returns>A boolean indicating if the specified entry was found.</returns> public bool ContainsDefaultKey(TKey key) { lock (_syncRoot) { if (LocalDefaults.ContainsKey(key)) { return(true); } for (var x = Parents.Count - 1; x >= 0; x--) { if (Parents[x].ContainsDefaultKey(key)) { return(true); } } return(false); } }
/// <summary> /// This removes a default entry matching the specified key "deeply". /// That is, it removes it from the top-level Defaults dictionary, /// and from all ancestor Default dictionaries in which it is found. /// </summary> /// <remarks>Traking info is also removed.</remarks> /// <param name="key">The key that specifies the default entry to be removed.</param> /// <returns>A boolean indicating if the specified entry was found and removed.</returns> public bool RemoveDefault(TKey key) { lock (_syncRoot) { var found = false; // First remove the default from each of the parents wherever it might be found. foreach (var parent in Parents.Where(parent => parent.RemoveDefault(key))) { found = true; } // Now remove the local default if it exists. if (LocalDefaults.Remove(key)) // Tracking info is also removed. { found = true; } return(found); } }
/// <summary> /// This operation is implemented to remain consistent with the IDictionary version. /// If the intent is only to remove a given KeyValuePair from the top-level collection, /// then Remove(..) should be used instead. /// </summary> /// <param name="item">The KeyValuePair to remove.</param> /// <returns>A boolean value indicating if the item was found and removed.</returns> public bool RemoveDeeply(KeyValuePair <TKey, TValue> item) { lock (_syncRoot) { // if we find it at the top-level, the we are done if (_localEntries.Remove(item)) { return(true); } // try the parents if (Parents.Any(parent => parent.RemoveDeeply(item))) { return(true); } // try the defaults return(LocalDefaults.Remove(item)); } }
public XElement ToXml() { var entries = LocalEntries.Select( entry => new XElement("parameter", new XAttribute("name", entry.Key), new XAttribute("value", entry.Value))).ToList(); var defaults = LocalDefaults.Select( def => new XElement("default", new XAttribute("name", def.Key), new XAttribute("value", def.Value))).ToList(); var parents = Parents.OfType <FileDictionaryTree>().Select(parent => parent.ToXml()).ToList(); var root = new XElement("dictionary"); if (!string.IsNullOrEmpty(Name)) { root.Add(new XAttribute("name", Name)); } if (!string.IsNullOrEmpty(FullName)) { root.Add(new XAttribute("fullName", FullName)); } if (entries.Count > 0) { root.Add(entries); } if (defaults.Count > 0) { root.Add(defaults); } if (parents.Count > 0) { root.Add(new XElement("parents", new XAttribute("count", parents.Count), parents)); } return(root); //return new XElement("dictionary", new XAttribute("name", FullName), // new XElement("entries", new XAttribute("count", LocalEntries.Count), entries), // new XElement("defaults", new XAttribute("count", LocalDefaults.Count), defaults), // new XElement("parents", new XAttribute("count", Parents.Count), parents)); }
/// <summary> /// This performs a deep search for the specified default key. /// That is, it first looks in the LocalDefaults dictionary, /// then in each LocalDefaults dictionary of the parents (from newest to oldest). /// If a "shallow" search is required, call "LocalDefaults.TryGetValue()" instead. /// </summary> /// <remarks>If the search is successful, the key is added to both the Accessed and Gotten lists.</remarks> /// <param name="key">The key that will be searched.</param> /// <param name="value">The out value of the entry if one is found.</param> /// <returns>A boolean indicating if the specified key and associated value were found.</returns> public bool TryGetDefault(TKey key, out TValue value) { lock (_syncRoot) { // finding it at the top-level means that we are done if (LocalDefaults.TryGetValue(key, out value)) { return(true); } // check each parent from newest to oldest for (var x = Parents.Count - 1; x >= 0; x--) { if (Parents[x].TryGetDefault(key, out value)) { return(true); } } return(false); } }