/// <summary> /// Sets a given value for a key defined by this object. /// </summary> /// <param name="key">The key to set the value for, that was defined before.</param> /// <param name="value">The value to set.</param> /// <remarks> /// <para> /// If the given <paramref name="key"/> was not previously defined, /// this method will add the key at this level of configuration /// </para> /// <para> /// Setting a value for a given <paramref name="key"/> that was already /// defined by a parent object will override that value: a subsequent call /// to <see cref="GetValue"/> will return the current value of the setting, /// without removing the parent value setting. /// </para> /// <para> /// If the key is formed to reference a child section, the value is /// set to the key parented by the referenced section. /// </para> /// </remarks> /// <exception cref="ArgumentNullException"> /// If the given <paramref name="key"/> is <c>null</c>. /// </exception> /// <seealso cref="SectionSeparator"/> public void SetValue(string key, object value) { if (String.IsNullOrEmpty(key)) { throw new ArgumentNullException(nameof(key)); } var parts = key.Split(SectionSeparator); if (parts.Length == 0) { throw new ArgumentException(); } if (parts.Length == 1) { if (value == null) { values.Remove(key); } else { values[key] = value; } } else { Configuration config = this; for (int i = 0; i < parts.Length; i++) { var part = parts[i]; if (i == parts.Length - 1) { config.SetValue(part, value); return; } var child = config.GetChild(part); if (child == null) { child = new Configuration(); config.AddSection(part, child); } else if (!(child is Configuration)) { throw new NotSupportedException(); } config = (Configuration)child; } } }