private static void SetDictionaryNodeGeneric <TKey, TValue>(Node node, Dictionary <TKey, TValue> dictionary, FileStyle style, bool forceArrayMode = false) { bool keyIsBase = BaseTypes.IsBaseType(typeof(TKey)); if (keyIsBase && !forceArrayMode && !style.AlwaysArrayDictionaries) { // we might have switched between standard and array dictionary storage, and if so, children need to be reset if (node.ChildNodeType != NodeChildrenType.key) { node.ClearChildren(newChildrenType: NodeChildrenType.key); } var CurrentKeys = new List <string>(capacity: dictionary.Count); foreach (var key in dictionary.Keys) { var value = dictionary[key]; string keyAsText = BaseTypes.SerializeBaseType <TKey>(key, style); if (!Utilities.IsValidKey(keyAsText)) { SetDictionaryNodeGeneric(node, dictionary, style, forceArrayMode: true); return; } CurrentKeys.Add(keyAsText); KeyNode child = node.GetChildAddressedByName(keyAsText); NodeManager.SetNodeData <TValue>(child, value, style); } // make sure that old data in the file is deleted when a new dictionary is saved. // node.ClearChildren() is not used because we want to keep comments and whitespace intact as much as possible. foreach (var key in node.GetChildKeys()) { if (!CurrentKeys.Contains(key)) { node.RemoveChild(key); } } } else // save dictionary as KeyValuePair<TKey, TValue>[] { // we might have switched between standard and array dictionary storage, and if so, children need to be reset if (node.ChildNodeType != NodeChildrenType.list) { node.ClearChildren(newChildrenType: NodeChildrenType.list); } var array = GetWritableKeyValuePairArray(dictionary); NodeManager.SetNodeData(node, array, array.GetType(), style); } }
/// <summary> Save this file as a dictionary, using the dictionary's keys as top-level keys in the file. </summary> /// <remarks> TKey must be a Base Type </remarks> public void SaveAsDictionary <TKey, TValue>(IDictionary <TKey, TValue> dictionary) { if (!BaseTypes.IsBaseType(typeof(TKey))) { throw new Exception("When using GetAsDictionary, TKey must be a base type"); } bool _autosave = AutoSave; AutoSave = false; // don't write to disk when we don't have to try { var CurrentKeys = new List <string>(capacity: dictionary.Count); foreach (var key in dictionary.Keys) { var keyText = BaseTypes.SerializeBaseType(key, Style); if (!Utilities.IsValidKey(keyText, out string whyNot)) { throw new Exception($"can't save file as this dictionary. A key ({keyText}) is not valid: {whyNot}"); } CurrentKeys.Add(keyText); Set(keyText, dictionary[key]); } // make sure that old data in the file is deleted when a new dictionary is saved. foreach (var key in this.TopLevelKeys) { if (!CurrentKeys.Contains(key)) { this.TopLevelNodes.Remove(key); } } } finally { AutoSave = _autosave; } if (AutoSave) { SaveAllData(); } }