JsonObject
public sealed class JsonObject : JsonNode, IDictionary<string, JsonNode>, ICollection<KeyValuePair<string, JsonNode>>, IEnumerable<KeyValuePair<string, JsonNode>>, IEnumerable, IList<KeyValuePair<string, JsonNode>>
Represents a mutable JSON object.
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization.Converters;
using System.Threading;
namespace System.Text.Json.Nodes
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
[DebuggerDisplay("JsonObject[{Count}]")]
[DebuggerTypeProxy(typeof(DebugView))]
public sealed class JsonObject : JsonNode, IDictionary<string, JsonNode>, ICollection<KeyValuePair<string, JsonNode>>, IEnumerable<KeyValuePair<string, JsonNode>>, IEnumerable, IList<KeyValuePair<string, JsonNode>>
{
[ExcludeFromCodeCoverage]
private sealed class DebugView
{
[DebuggerDisplay("{Display,nq}")]
private struct DebugViewProperty
{
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public JsonNode Value;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public string PropertyName;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public string Display {
get {
if (Value == null)
return PropertyName + " = null";
if (Value is JsonValue)
return PropertyName + " = " + Value.ToJsonString(null);
JsonObject jsonObject = Value as JsonObject;
if (jsonObject != null)
return $"{PropertyName}""{jsonObject.Count}""";
JsonArray jsonArray = (JsonArray)Value;
return $"{PropertyName}""{jsonArray.Count}""";
}
}
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly JsonObject _node;
public string Json => _node.ToJsonString(null);
public string Path => _node.GetPath();
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
private DebugViewProperty[] Items {
get {
DebugViewProperty[] array = new DebugViewProperty[_node.Count];
int num = 0;
foreach (KeyValuePair<string, JsonNode> item in _node) {
array[num].PropertyName = item.Key;
array[num].Value = item.Value;
num++;
}
return array;
}
}
public DebugView(JsonObject node)
{
_node = node;
}
}
private JsonElement? _jsonElement;
private System.Collections.Generic.OrderedDictionary<string, JsonNode> _dictionary;
internal override JsonElement? UnderlyingElement => _jsonElement;
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
2
})]
private System.Collections.Generic.OrderedDictionary<string, JsonNode> Dictionary {
get {
return _dictionary ?? InitializeDictionary();
}
}
public int Count => Dictionary.Count;
ICollection<string> IDictionary<string, JsonNode>.Keys {
get {
return Dictionary.Keys;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
2
})]
ICollection<JsonNode> IDictionary<string, JsonNode>.Values {
get {
return Dictionary.Values;
}
}
bool ICollection<KeyValuePair<string, JsonNode>>.IsReadOnly {
get {
return false;
}
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
2
})]
KeyValuePair<string, JsonNode> IList<KeyValuePair<string, JsonNode>>.this[int index] {
get {
return GetAt(index);
}
set {
SetAt(index, value.Key, value.Value);
}
}
public JsonObject(JsonNodeOptions? options = default(JsonNodeOptions?))
: base(options)
{
}
public JsonObject([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1,
2
})] IEnumerable<KeyValuePair<string, JsonNode>> properties, JsonNodeOptions? options = default(JsonNodeOptions?))
: this(options)
{
ICollection<KeyValuePair<string, JsonNode>> collection = properties as ICollection<KeyValuePair<string, JsonNode>>;
int capacity = (collection != null) ? collection.Count : 0;
System.Collections.Generic.OrderedDictionary<string, JsonNode> orderedDictionary = CreateDictionary(options, capacity);
foreach (KeyValuePair<string, JsonNode> property in properties) {
orderedDictionary.Add(property.Key, property.Value);
property.Value?.AssignParent(this);
}
_dictionary = orderedDictionary;
}
[System.Runtime.CompilerServices.NullableContext(2)]
public static JsonObject Create(JsonElement element, JsonNodeOptions? options = default(JsonNodeOptions?))
{
switch (element.ValueKind) {
case JsonValueKind.Null:
return null;
case JsonValueKind.Object:
return new JsonObject(element, options);
default:
throw new InvalidOperationException(System.SR.Format(System.SR.NodeElementWrongType, "Object"));
}
}
internal JsonObject(JsonElement element, JsonNodeOptions? options = default(JsonNodeOptions?))
: this(options)
{
_jsonElement = element;
}
private protected override JsonNode GetItem(int index)
{
return GetAt(index).Value;
}
private protected override void SetItem(int index, JsonNode value)
{
SetAt(index, value);
}
internal override JsonNode DeepCloneCore()
{
GetUnderlyingRepresentation(out System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary, out JsonElement? jsonElement);
if (dictionary == null) {
if (!jsonElement.HasValue)
return new JsonObject(base.Options);
return new JsonObject(jsonElement.Value.Clone(), base.Options);
}
JsonObject jsonObject = new JsonObject(base.Options) {
_dictionary = CreateDictionary(base.Options, Count)
};
foreach (KeyValuePair<string, JsonNode> item in dictionary) {
jsonObject.Add(item.Key, item.Value?.DeepCloneCore());
}
return jsonObject;
}
internal string GetPropertyName(JsonNode node)
{
KeyValuePair<string, JsonNode>? nullable = FindValue(node);
if (!nullable.HasValue)
return string.Empty;
return nullable.Value.Key;
}
public bool TryGetPropertyValue(string propertyName, [System.Runtime.CompilerServices.Nullable(2)] out JsonNode jsonNode)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
return Dictionary.TryGetValue(propertyName, out jsonNode);
}
public override void WriteTo(Utf8JsonWriter writer, [System.Runtime.CompilerServices.Nullable(2)] JsonSerializerOptions options = null)
{
if (writer == null)
ThrowHelper.ThrowArgumentNullException("writer");
GetUnderlyingRepresentation(out System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary, out JsonElement? jsonElement);
if (dictionary == null && jsonElement.HasValue)
jsonElement.Value.WriteTo(writer);
else {
writer.WriteStartObject();
foreach (KeyValuePair<string, JsonNode> item in Dictionary) {
writer.WritePropertyName(item.Key);
if (item.Value == null)
writer.WriteNullValue();
else
item.Value.WriteTo(writer, options);
}
writer.WriteEndObject();
}
}
private protected override JsonValueKind GetValueKindCore()
{
return JsonValueKind.Object;
}
internal override bool DeepEqualsCore(JsonNode node)
{
if (node is JsonArray)
return false;
JsonValue jsonValue = node as JsonValue;
if (jsonValue != null)
return jsonValue.DeepEqualsCore(this);
JsonObject jsonObject = node as JsonObject;
if (jsonObject != null) {
System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary = Dictionary;
System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary2 = jsonObject.Dictionary;
if (dictionary.Count != dictionary2.Count)
return false;
foreach (KeyValuePair<string, JsonNode> item in dictionary) {
dictionary2.TryGetValue(item.Key, out JsonNode value);
if (!JsonNode.DeepEquals(item.Value, value))
return false;
}
return true;
}
return false;
}
internal JsonNode GetItem(string propertyName)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
if (TryGetPropertyValue(propertyName, out JsonNode jsonNode))
return jsonNode;
return null;
}
internal override void GetPath(ref System.Text.ValueStringBuilder path, JsonNode child)
{
base.Parent?.GetPath(ref path, this);
if (child != null) {
string key = FindValue(child).Value.Key;
if (key.AsSpan().ContainsSpecialCharacters()) {
path.Append("['");
path.Append(key);
path.Append("']");
} else {
path.Append('.');
path.Append(key);
}
}
}
internal void SetItem(string propertyName, JsonNode value)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary = Dictionary;
if (!dictionary.TryAdd(propertyName, value)) {
int index = dictionary.IndexOf(propertyName);
JsonNode value2 = dictionary.GetAt(index).Value;
if (value == value2)
return;
DetachParent(value2);
dictionary.SetAt(index, value);
}
value?.AssignParent(this);
}
private void DetachParent(JsonNode item)
{
if (item != null)
item.Parent = null;
}
private KeyValuePair<string, JsonNode>? FindValue(JsonNode value)
{
foreach (KeyValuePair<string, JsonNode> item in Dictionary) {
if (item.Value == value)
return item;
}
return null;
}
public void Add(string propertyName, [System.Runtime.CompilerServices.Nullable(2)] JsonNode value)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
Dictionary.Add(propertyName, value);
value?.AssignParent(this);
}
public void Add([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
2
})] KeyValuePair<string, JsonNode> property)
{
Add(property.Key, property.Value);
}
public void Clear()
{
System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary = _dictionary;
if (dictionary == null)
_jsonElement = null;
else {
foreach (JsonNode value in dictionary.Values) {
DetachParent(value);
}
dictionary.Clear();
}
}
public bool ContainsKey(string propertyName)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
return Dictionary.ContainsKey(propertyName);
}
public bool Remove(string propertyName)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
JsonNode value;
bool num = Dictionary.Remove(propertyName, out value);
if (num)
DetachParent(value);
return num;
}
bool ICollection<KeyValuePair<string, JsonNode>>.Contains(KeyValuePair<string, JsonNode> item)
{
return ((ICollection<KeyValuePair<string, JsonNode>>)Dictionary).Contains(item);
}
void ICollection<KeyValuePair<string, JsonNode>>.CopyTo(KeyValuePair<string, JsonNode>[] array, int index)
{
((ICollection<KeyValuePair<string, JsonNode>>)Dictionary).CopyTo(array, index);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1,
2
})]
public IEnumerator<KeyValuePair<string, JsonNode>> GetEnumerator()
{
return Dictionary.GetEnumerator();
}
bool ICollection<KeyValuePair<string, JsonNode>>.Remove(KeyValuePair<string, JsonNode> item)
{
return Remove(item.Key);
}
bool IDictionary<string, JsonNode>.TryGetValue(string propertyName, out JsonNode jsonNode)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
return Dictionary.TryGetValue(propertyName, out jsonNode);
}
IEnumerator IEnumerable.GetEnumerator()
{
return Dictionary.GetEnumerator();
}
private System.Collections.Generic.OrderedDictionary<string, JsonNode> InitializeDictionary()
{
GetUnderlyingRepresentation(out System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary, out JsonElement? jsonElement);
if (dictionary == null) {
dictionary = CreateDictionary(base.Options, 0);
if (jsonElement.HasValue) {
foreach (JsonProperty item in jsonElement.Value.EnumerateObject()) {
JsonNode jsonNode = JsonNodeConverter.Create(item.Value, base.Options);
if (jsonNode != null)
jsonNode.Parent = this;
dictionary.Add(item.Name, jsonNode);
}
}
_dictionary = dictionary;
Interlocked.MemoryBarrier();
_jsonElement = null;
}
return dictionary;
}
private static System.Collections.Generic.OrderedDictionary<string, JsonNode> CreateDictionary(JsonNodeOptions? options, int capacity = 0)
{
StringComparer comparer = (options?.PropertyNameCaseInsensitive ?? false) ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal;
return new System.Collections.Generic.OrderedDictionary<string, JsonNode>(capacity, comparer);
}
private void GetUnderlyingRepresentation(out System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary, out JsonElement? jsonElement)
{
jsonElement = _jsonElement;
Interlocked.MemoryBarrier();
dictionary = _dictionary;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
2
})]
public KeyValuePair<string, JsonNode> GetAt(int index)
{
return Dictionary.GetAt(index);
}
public void SetAt(int index, string propertyName, [System.Runtime.CompilerServices.Nullable(2)] JsonNode value)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary = Dictionary;
KeyValuePair<string, JsonNode> at = dictionary.GetAt(index);
dictionary.SetAt(index, propertyName, value);
DetachParent(at.Value);
value?.AssignParent(this);
}
[System.Runtime.CompilerServices.NullableContext(2)]
public void SetAt(int index, JsonNode value)
{
System.Collections.Generic.OrderedDictionary<string, JsonNode> dictionary = Dictionary;
KeyValuePair<string, JsonNode> at = dictionary.GetAt(index);
dictionary.SetAt(index, value);
DetachParent(at.Value);
value?.AssignParent(this);
}
public int IndexOf(string propertyName)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
return Dictionary.IndexOf(propertyName);
}
public void Insert(int index, string propertyName, [System.Runtime.CompilerServices.Nullable(2)] JsonNode value)
{
if (propertyName == null)
ThrowHelper.ThrowArgumentNullException("propertyName");
Dictionary.Insert(index, propertyName, value);
value?.AssignParent(this);
}
public void RemoveAt(int index)
{
KeyValuePair<string, JsonNode> at = Dictionary.GetAt(index);
Dictionary.RemoveAt(index);
DetachParent(at.Value);
}
int IList<KeyValuePair<string, JsonNode>>.IndexOf(KeyValuePair<string, JsonNode> item)
{
return ((IList<KeyValuePair<string, JsonNode>>)Dictionary).IndexOf(item);
}
void IList<KeyValuePair<string, JsonNode>>.Insert(int index, KeyValuePair<string, JsonNode> item)
{
Insert(index, item.Key, item.Value);
}
void IList<KeyValuePair<string, JsonNode>>.RemoveAt(int index)
{
RemoveAt(index);
}
}
}