/// <inheritdoc/> public IPropertyBag CreateModified( IPropertyBag input, IEnumerable <KeyValuePair <string, object> >?propertiesToSetOrAdd, IEnumerable <string>?propertiesToRemove) { IReadOnlyDictionary <string, object> existingProperties = input.AsDictionary(); Dictionary <string, object> newProperties = propertiesToSetOrAdd?.ToDictionary(kv => kv.Key, kv => kv.Value) ?? new Dictionary <string, object>(); HashSet <string>?remove = propertiesToRemove == null ? null : new HashSet <string>(propertiesToRemove); foreach (KeyValuePair <string, object> existingKv in existingProperties) { string key = existingKv.Key; bool newPropertyWithThisNameExists = newProperties.ContainsKey(key); bool existingPropertyIsToBeRemoved = remove?.Contains(key) == true; if (newPropertyWithThisNameExists && existingPropertyIsToBeRemoved) { throw new ArgumentException($"Property {key} appears in both {nameof(propertiesToSetOrAdd)} and {nameof(propertiesToRemove)}"); } if (!newPropertyWithThisNameExists && !existingPropertyIsToBeRemoved) { newProperties.Add(key, existingKv.Value); } } return(new JsonNetPropertyBag(newProperties, this.serializerSettings)); }
/// <summary> /// Retrieves the properties as a dictionary. /// </summary> /// <param name="propertyBag">The <see cref="IPropertyBag"/> to convert.</param> /// <returns>A dictionary containing all of the properties in the bag.</returns> /// <remarks> /// <para> /// This method extends the <see cref="AsDictionary"/> method by recursively processing the /// result dictionary and converting any nested <see cref="IPropertyBag"/> instances to further /// <see cref="IReadOnlyDictionary{TKey, TValue}"/>s. /// </para> /// <para> /// As a result, this is a potentially expensive operation. It should not be called repeatedly; the result from /// a call should be stored and reused. /// </para> /// </remarks> public static IReadOnlyDictionary <string, object> AsDictionaryRecursive(this IPropertyBag propertyBag) { return(RecursivelyProcessDictionary(propertyBag.AsDictionary())); }