< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 296
Coverable lines: 296
Total lines: 815
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 104
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
File 1: .ctor(...)100%110%
File 1: .ctor(...)0%660%
File 1: Create(...)0%440%
File 1: .ctor(...)100%110%
File 1: GetItem(...)100%110%
File 1: SetItem(...)100%110%
File 1: DeepCloneCore()0%880%
File 1: GetPropertyName(...)0%220%
File 1: TryGetPropertyValue(...)100%110%
File 1: TryGetPropertyValue(...)100%110%
File 1: WriteTo(...)0%440%
File 1: WriteContentsTo(...)0%10100%
File 1: GetValueKindCore()100%110%
File 1: DeepEqualsCore(...)0%14140%
File 1: GetItem(...)0%220%
File 1: GetPath(...)0%660%
File 1: SetItem(...)0%660%
File 1: DetachParent(...)0%220%
File 1: FindValue(...)0%440%
File 2: Add(...)0%220%
File 2: TryAdd(...)100%110%
File 2: TryAdd(...)0%660%
File 2: Add(...)100%110%
File 2: Clear()0%440%
File 2: ContainsKey(...)100%110%
File 2: Remove(...)0%220%
File 2: System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.Contains(...)100%110%
File 2: System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.CopyTo(...)100%110%
File 2: GetEnumerator()100%110%
File 2: System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.Remove(...)100%110%
File 2: System.Collections.Generic.IDictionary<System.String,System.Text.Json.Nodes.JsonNode>.TryGetValue(...)100%110%
File 2: System.Collections.IEnumerable.GetEnumerator()100%110%
File 2: InitializeDictionary()0%10100%
File 2: CreateDictionary(...)0%440%
File 2: GetUnderlyingRepresentation(...)100%110%
File 3: GetAt(...)100%110%
File 3: SetAt(...)0%220%
File 3: SetAt(...)0%220%
File 3: IndexOf(...)100%110%
File 3: Insert(...)0%220%
File 3: RemoveAt(...)100%110%
File 3: System.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.IndexOf(...)100%110%
File 3: System.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.Insert(...)100%110%
File 3: System.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.RemoveAt(...)100%110%

File(s)

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\Nodes\JsonObject.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Generic;
 5using System.Diagnostics;
 6using System.Diagnostics.CodeAnalysis;
 7
 8namespace System.Text.Json.Nodes
 9{
 10    /// <summary>
 11    ///   Represents a mutable JSON object.
 12    /// </summary>
 13    /// <remarks>
 14    /// It's safe to perform multiple concurrent read operations on a <see cref="JsonObject"/>,
 15    /// but issues can occur if the collection is modified while it's being read.
 16    /// </remarks>
 17    [DebuggerDisplay("JsonObject[{Count}]")]
 18    [DebuggerTypeProxy(typeof(DebugView))]
 19    public sealed partial class JsonObject : JsonNode
 20    {
 21        private JsonElement? _jsonElement;
 22
 023        internal override JsonElement? UnderlyingElement => _jsonElement;
 24
 25        /// <summary>
 26        ///   Initializes a new instance of the <see cref="JsonObject"/> class that is empty.
 27        /// </summary>
 28        /// <param name="options">Options to control the behavior.</param>
 029        public JsonObject(JsonNodeOptions? options = null) : base(options) { }
 30
 31        /// <summary>
 32        ///   Initializes a new instance of the <see cref="JsonObject"/> class that contains the specified <paramref nam
 33        /// </summary>
 34        /// <param name="properties">The properties to be added.</param>
 35        /// <param name="options">Options to control the behavior.</param>
 036        public JsonObject(IEnumerable<KeyValuePair<string, JsonNode?>> properties, JsonNodeOptions? options = null) : th
 037        {
 038            int capacity = properties is ICollection<KeyValuePair<string, JsonNode?>> propertiesCollection ? propertiesC
 039            OrderedDictionary<string, JsonNode?> dictionary = CreateDictionary(options, capacity);
 40
 041            foreach (KeyValuePair<string, JsonNode?> node in properties)
 042            {
 043                dictionary.Add(node.Key, node.Value);
 044                node.Value?.AssignParent(this);
 045            }
 46
 047            _dictionary = dictionary;
 048        }
 49
 50        /// <summary>
 51        ///   Initializes a new instance of the <see cref="JsonObject"/> class that contains properties from the specifi
 52        /// </summary>
 53        /// <returns>
 54        ///   The new instance of the <see cref="JsonObject"/> class that contains properties from the specified <see cr
 55        /// </returns>
 56        /// <param name="element">The <see cref="JsonElement"/>.</param>
 57        /// <param name="options">Options to control the behavior.</param>
 58        /// <returns>A <see cref="JsonObject"/>.</returns>
 59        public static JsonObject? Create(JsonElement element, JsonNodeOptions? options = null)
 060        {
 061            return element.ValueKind switch
 062            {
 063                JsonValueKind.Null => null,
 064                JsonValueKind.Object => new JsonObject(element, options),
 065                _ => throw new InvalidOperationException(SR.Format(SR.NodeElementWrongType, nameof(JsonValueKind.Object)
 066            };
 067        }
 68
 069        internal JsonObject(JsonElement element, JsonNodeOptions? options = null) : this(options)
 070        {
 071            Debug.Assert(element.ValueKind == JsonValueKind.Object);
 072            _jsonElement = element;
 073        }
 74
 75        /// <summary>
 76        /// Gets or creates the underlying dictionary containing the properties of the object.
 77        /// </summary>
 078        private OrderedDictionary<string, JsonNode?> Dictionary => _dictionary ?? InitializeDictionary();
 79
 080        private protected override JsonNode? GetItem(int index) => GetAt(index).Value;
 081        private protected override void SetItem(int index, JsonNode? value) => SetAt(index, value);
 82
 83        internal override JsonNode DeepCloneCore()
 084        {
 085            GetUnderlyingRepresentation(out OrderedDictionary<string, JsonNode?>? dictionary, out JsonElement? jsonEleme
 86
 087            if (dictionary is null)
 088            {
 089                return jsonElement.HasValue
 090                    ? new JsonObject(jsonElement.Value.Clone(), Options)
 091                    : new JsonObject(Options);
 92            }
 93
 094            var jObject = new JsonObject(Options)
 095            {
 096                _dictionary = CreateDictionary(Options, Count)
 097            };
 98
 099            foreach (KeyValuePair<string, JsonNode?> item in dictionary)
 0100            {
 0101                jObject.Add(item.Key, item.Value?.DeepCloneCore());
 0102            }
 103
 0104            return jObject;
 0105        }
 106
 107        internal string GetPropertyName(JsonNode? node)
 0108        {
 0109            KeyValuePair<string, JsonNode?>? item = FindValue(node);
 0110            return item.HasValue ? item.Value.Key : string.Empty;
 0111        }
 112
 113        /// <summary>
 114        ///   Returns the value of a property with the specified name.
 115        /// </summary>
 116        /// <param name="propertyName">The name of the property to return.</param>
 117        /// <param name="jsonNode">The JSON value of the property with the specified name.</param>
 118        /// <exception cref="ArgumentNullException">
 119        ///   <paramref name="propertyName"/> is <see langword="null"/>.
 120        /// </exception>
 121        /// <returns>
 122        ///   <see langword="true"/> if a property with the specified name was found; otherwise, <see langword="false"/>
 123        /// </returns>
 0124        public bool TryGetPropertyValue(string propertyName, out JsonNode? jsonNode) => TryGetPropertyValue(propertyName
 125
 126        /// <summary>
 127        ///   Gets the value associated with the specified property name.
 128        /// </summary>
 129        /// <param name="propertyName">The property name of the value to get.</param>
 130        /// <param name="jsonNode">
 131        ///   When this method returns, it contains the value associated with the specified property name, if the proper
 132        ///   otherwise <see langword="null"/>.
 133        /// </param>
 134        /// <param name="index">The index of <paramref name="propertyName"/> if found; otherwise, -1.</param>
 135        /// <exception cref="ArgumentNullException">
 136        ///   <paramref name="propertyName"/> is <see langword="null"/>.
 137        /// </exception>
 138        /// <returns>
 139        ///   <see langword="true"/> if the <see cref="JsonObject"/> contains an element with the specified property nam
 140        /// </returns>
 141        public bool TryGetPropertyValue(string propertyName, out JsonNode? jsonNode, out int index)
 0142        {
 0143            ArgumentNullException.ThrowIfNull(propertyName);
 144
 145#if NET9_0
 146            index = Dictionary.IndexOf(propertyName);
 147            if (index < 0)
 148            {
 149                jsonNode = null;
 150                return false;
 151            }
 152
 153            jsonNode = Dictionary.GetAt(index).Value;
 154            return true;
 155#else
 0156            return Dictionary.TryGetValue(propertyName, out jsonNode, out index);
 157#endif
 0158        }
 159
 160        /// <inheritdoc/>
 161        public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null)
 0162        {
 0163            ArgumentNullException.ThrowIfNull(writer);
 164
 0165            GetUnderlyingRepresentation(out OrderedDictionary<string, JsonNode?>? dictionary, out JsonElement? jsonEleme
 166
 0167            if (dictionary is null && jsonElement.HasValue)
 0168            {
 169                // Write the element without converting to nodes.
 0170                jsonElement.Value.WriteTo(writer);
 0171            }
 172            else
 0173            {
 0174                writer.WriteStartObject();
 0175                WriteContentsTo(writer, options);
 0176                writer.WriteEndObject();
 0177            }
 0178        }
 179
 180        /// <summary>
 181        /// Writes the properties of this JsonObject to the writer without the surrounding braces.
 182        /// This is used for extension data serialization where the properties should be flattened
 183        /// into the parent object.
 184        /// </summary>
 185        internal void WriteContentsTo(Utf8JsonWriter writer, JsonSerializerOptions? options)
 0186        {
 0187            GetUnderlyingRepresentation(out OrderedDictionary<string, JsonNode?>? dictionary, out JsonElement? jsonEleme
 188
 0189            if (dictionary is null && jsonElement.HasValue)
 0190            {
 191                // Write properties from the underlying JsonElement without converting to nodes.
 0192                foreach (JsonProperty property in jsonElement.Value.EnumerateObject())
 0193                {
 0194                    property.WriteTo(writer);
 0195                }
 0196            }
 197            else
 0198            {
 0199                foreach (KeyValuePair<string, JsonNode?> entry in Dictionary)
 0200                {
 0201                    writer.WritePropertyName(entry.Key);
 202
 0203                    if (entry.Value is null)
 0204                    {
 0205                        writer.WriteNullValue();
 0206                    }
 207                    else
 0208                    {
 0209                        entry.Value.WriteTo(writer, options);
 0210                    }
 0211                }
 0212            }
 0213        }
 214
 0215        private protected override JsonValueKind GetValueKindCore() => JsonValueKind.Object;
 216
 217        internal override bool DeepEqualsCore(JsonNode node)
 0218        {
 0219            switch (node)
 220            {
 221                case JsonArray:
 0222                    return false;
 223                case JsonValue value:
 224                    // JsonValue instances have special comparison semantics, dispatch to their implementation.
 0225                    return value.DeepEqualsCore(this);
 226                case JsonObject jsonObject:
 0227                    OrderedDictionary<string, JsonNode?> currentDict = Dictionary;
 0228                    OrderedDictionary<string, JsonNode?> otherDict = jsonObject.Dictionary;
 229
 0230                    if (currentDict.Count != otherDict.Count)
 0231                    {
 0232                        return false;
 233                    }
 234
 0235                    foreach (KeyValuePair<string, JsonNode?> item in currentDict)
 0236                    {
 0237                        if (!otherDict.TryGetValue(item.Key, out JsonNode? jsonNode) || !DeepEquals(item.Value, jsonNode
 0238                        {
 0239                            return false;
 240                        }
 0241                    }
 242
 0243                    return true;
 244                default:
 0245                    Debug.Fail("Impossible case");
 246                    return false;
 247            }
 0248        }
 249
 250        internal JsonNode? GetItem(string propertyName)
 0251        {
 0252            ArgumentNullException.ThrowIfNull(propertyName);
 253
 0254            if (TryGetPropertyValue(propertyName, out JsonNode? value))
 0255            {
 0256                return value;
 257            }
 258
 259            // Return null for missing properties.
 0260            return null;
 0261        }
 262
 263        internal override void GetPath(ref ValueStringBuilder path, JsonNode? child)
 0264        {
 0265            Parent?.GetPath(ref path, this);
 266
 0267            if (child != null)
 0268            {
 0269                string propertyName = FindValue(child)!.Value.Key;
 0270                if (propertyName.AsSpan().ContainsSpecialCharacters())
 0271                {
 0272                    path.Append("['");
 0273                    path.AppendEscapedPropertyName(propertyName);
 0274                    path.Append("']");
 0275                }
 276                else
 0277                {
 0278                    path.Append('.');
 0279                    path.Append(propertyName);
 0280                }
 0281            }
 0282        }
 283
 284        internal void SetItem(string propertyName, JsonNode? value)
 0285        {
 0286            ArgumentNullException.ThrowIfNull(propertyName);
 287
 0288            OrderedDictionary<string, JsonNode?> dict = Dictionary;
 289
 0290            if (
 0291#if NET9_0
 0292                !dict.TryAdd(propertyName, value)
 0293#else
 0294                !dict.TryAdd(propertyName, value, out int index)
 0295#endif
 0296                )
 0297            {
 298#if NET9_0
 299                int index = dict.IndexOf(propertyName);
 300#endif
 0301                Debug.Assert(index >= 0);
 0302                JsonNode? replacedValue = dict.GetAt(index).Value;
 303
 0304                if (ReferenceEquals(value, replacedValue))
 0305                {
 0306                    return;
 307                }
 308
 0309                DetachParent(replacedValue);
 0310                dict.SetAt(index, value);
 0311            }
 312
 0313            value?.AssignParent(this);
 0314        }
 315
 316        private void DetachParent(JsonNode? item)
 0317        {
 0318            Debug.Assert(_dictionary != null, "Cannot have detachable nodes without a materialized dictionary.");
 319
 0320            item?.Parent = null;
 0321        }
 322
 323        private KeyValuePair<string, JsonNode?>? FindValue(JsonNode? value)
 0324        {
 0325            foreach (KeyValuePair<string, JsonNode?> item in Dictionary)
 0326            {
 0327                if (ReferenceEquals(item.Value, value))
 0328                {
 0329                    return item;
 330                }
 0331            }
 332
 0333            return null;
 0334        }
 335
 336        [ExcludeFromCodeCoverage] // Justification = "Design-time"
 337        private sealed class DebugView
 338        {
 339            [DebuggerBrowsable(DebuggerBrowsableState.Never)]
 340            private readonly JsonObject _node;
 341
 342            public DebugView(JsonObject node)
 343            {
 344                _node = node;
 345            }
 346
 347            public string Json => _node.ToJsonString();
 348            public string Path => _node.GetPath();
 349
 350            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
 351            private DebugViewProperty[] Items
 352            {
 353                get
 354                {
 355                    DebugViewProperty[] properties = new DebugViewProperty[_node.Count];
 356
 357                    int i = 0;
 358                    foreach (KeyValuePair<string, JsonNode?> item in _node)
 359                    {
 360                        properties[i].PropertyName = item.Key;
 361                        properties[i].Value = item.Value;
 362                        i++;
 363                    }
 364
 365                    return properties;
 366                }
 367            }
 368
 369            [DebuggerDisplay("{Display,nq}")]
 370            private struct DebugViewProperty
 371            {
 372                [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
 373                public JsonNode? Value;
 374
 375                [DebuggerBrowsable(DebuggerBrowsableState.Never)]
 376                public string PropertyName;
 377
 378                [DebuggerBrowsable(DebuggerBrowsableState.Never)]
 379                public string Display
 380                {
 381                    get
 382                    {
 383                        if (Value == null)
 384                        {
 385                            return $"{PropertyName} = null";
 386                        }
 387
 388                        if (Value is JsonValue)
 389                        {
 390                            return $"{PropertyName} = {Value.ToJsonString()}";
 391                        }
 392
 393                        if (Value is JsonObject jsonObject)
 394                        {
 395                            return $"{PropertyName} = JsonObject[{jsonObject.Count}]";
 396                        }
 397
 398                        JsonArray jsonArray = (JsonArray)Value;
 399                        return $"{PropertyName} = JsonArray[{jsonArray.Count}]";
 400                    }
 401                }
 402
 403            }
 404        }
 405    }
 406}

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\Nodes\JsonObject.IDictionary.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections;
 5using System.Collections.Generic;
 6using System.Text.Json.Serialization.Converters;
 7using System.Threading;
 8
 9namespace System.Text.Json.Nodes
 10{
 11    public partial class JsonObject : IDictionary<string, JsonNode?>
 12    {
 13        private OrderedDictionary<string, JsonNode?>? _dictionary;
 14
 15        /// <summary>
 16        ///   Adds an element with the provided property name and value to the <see cref="JsonObject"/>.
 17        /// </summary>
 18        /// <param name="propertyName">The property name of the element to add.</param>
 19        /// <param name="value">The value of the element to add.</param>
 20        /// <exception cref="ArgumentNullException">
 21        ///   <paramref name="propertyName"/>is <see langword="null"/>.
 22        /// </exception>
 23        /// <exception cref="ArgumentException">
 24        ///   An element with the same property name already exists in the <see cref="JsonObject"/>.
 25        /// </exception>
 26        public void Add(string propertyName, JsonNode? value)
 027        {
 028            ArgumentNullException.ThrowIfNull(propertyName);
 29
 030            Dictionary.Add(propertyName, value);
 031            value?.AssignParent(this);
 032        }
 33
 34        /// <summary>
 35        ///   Adds an element with the provided name and value to the <see cref="JsonObject"/>, if a property named <par
 36        /// </summary>
 37        /// <param name="propertyName">The property name of the element to add.</param>
 38        /// <param name="value">The value of the element to add.</param>
 39        /// <exception cref="ArgumentNullException"><paramref name="propertyName"/> is null.</exception>
 40        /// <returns>
 41        ///   <see langword="true"/> if the property didn't exist and the element was added; otherwise, <see langword="f
 42        /// </returns>
 043        public bool TryAdd(string propertyName, JsonNode? value) => TryAdd(propertyName, value, out _);
 44
 45        /// <summary>
 46        ///   Adds an element with the provided name and value to the <see cref="JsonObject"/>, if a property named <par
 47        /// </summary>
 48        /// <param name="propertyName">The property name of the element to add.</param>
 49        /// <param name="value">The value of the element to add.</param>
 50        /// <param name="index">The index of the added or existing <paramref name="propertyName"/>. This is always a val
 51        /// <exception cref="ArgumentNullException"><paramref name="propertyName"/> is null.</exception>
 52        /// <returns>
 53        ///   <see langword="true"/> if the property didn't exist and the element was added; otherwise, <see langword="f
 54        /// </returns>
 55        public bool TryAdd(string propertyName, JsonNode? value, out int index)
 056        {
 057            if (propertyName is null)
 058            {
 059                ThrowHelper.ThrowArgumentNullException(nameof(propertyName));
 60            }
 61#if NET9_0
 62            bool success = Dictionary.TryAdd(propertyName, value);
 63            index = success ? Dictionary.Count - 1 : Dictionary.IndexOf(propertyName);
 64#else
 065            bool success = Dictionary.TryAdd(propertyName, value, out index);
 66#endif
 067            if (success)
 068            {
 069                value?.AssignParent(this);
 070            }
 071            return success;
 072        }
 73
 74        /// <summary>
 75        ///   Adds the specified property to the <see cref="JsonObject"/>.
 76        /// </summary>
 77        /// <param name="property">
 78        ///   The KeyValuePair structure representing the property name and value to add to the <see cref="JsonObject"/>
 79        /// </param>
 80        /// <exception cref="ArgumentException">
 81        ///   An element with the same property name already exists in the <see cref="JsonObject"/>.
 82        /// </exception>
 83        /// <exception cref="ArgumentNullException">
 84        ///   The property name of <paramref name="property"/> is <see langword="null"/>.
 85        /// </exception>
 086        public void Add(KeyValuePair<string, JsonNode?> property) => Add(property.Key, property.Value);
 87
 88        /// <summary>
 89        ///   Removes all elements from the <see cref="JsonObject"/>.
 90        /// </summary>
 91        public void Clear()
 092        {
 093            OrderedDictionary<string, JsonNode?>? dictionary = _dictionary;
 94
 095            if (dictionary is null)
 096            {
 097                _jsonElement = null;
 098                return;
 99            }
 100
 0101            foreach (JsonNode? node in dictionary.Values)
 0102            {
 0103                DetachParent(node);
 0104            }
 105
 0106            dictionary.Clear();
 0107        }
 108
 109        /// <summary>
 110        ///   Determines whether the <see cref="JsonObject"/> contains an element with the specified property name.
 111        /// </summary>
 112        /// <param name="propertyName">The property name to locate in the <see cref="JsonObject"/>.</param>
 113        /// <returns>
 114        ///   <see langword="true"/> if the <see cref="JsonObject"/> contains an element with the specified property nam
 115        /// </returns>
 116        /// <exception cref="ArgumentNullException">
 117        ///   <paramref name="propertyName"/> is <see langword="null"/>.
 118        /// </exception>
 119        public bool ContainsKey(string propertyName)
 0120        {
 0121            ArgumentNullException.ThrowIfNull(propertyName);
 122
 0123            return Dictionary.ContainsKey(propertyName);
 0124        }
 125
 126        /// <summary>
 127        ///   Gets the number of elements contained in <see cref="JsonObject"/>.
 128        /// </summary>
 0129        public int Count => Dictionary.Count;
 130
 131        /// <summary>
 132        ///   Removes the element with the specified property name from the <see cref="JsonObject"/>.
 133        /// </summary>
 134        /// <param name="propertyName">The property name of the element to remove.</param>
 135        /// <returns>
 136        ///   <see langword="true"/> if the element is successfully removed; otherwise, <see langword="false"/>.
 137        /// </returns>
 138        /// <exception cref="ArgumentNullException">
 139        ///   <paramref name="propertyName"/> is <see langword="null"/>.
 140        /// </exception>
 141        public bool Remove(string propertyName)
 0142        {
 0143            ArgumentNullException.ThrowIfNull(propertyName);
 144
 0145            bool success = Dictionary.Remove(propertyName, out JsonNode? removedNode);
 0146            if (success)
 0147            {
 0148                DetachParent(removedNode);
 0149            }
 150
 0151            return success;
 0152        }
 153
 154        /// <summary>
 155        ///   Determines whether the <see cref="JsonObject"/> contains a specific property name and <see cref="JsonNode"
 156        /// </summary>
 157        /// <param name="item">The element to locate in the <see cref="JsonObject"/>.</param>
 158        /// <returns>
 159        ///   <see langword="true"/> if the <see cref="JsonObject"/> contains an element with the property name; otherwi
 160        /// </returns>
 161        bool ICollection<KeyValuePair<string, JsonNode?>>.Contains(KeyValuePair<string, JsonNode?> item) =>
 0162            ((IDictionary<string, JsonNode?>)Dictionary).Contains(item);
 163
 164        /// <summary>
 165        ///   Copies the elements of the <see cref="JsonObject"/> to an array of type KeyValuePair starting at the speci
 166        /// </summary>
 167        /// <param name="array">
 168        ///   The one-dimensional Array that is the destination of the elements copied from <see cref="JsonObject"/>.
 169        /// </param>
 170        /// <param name="index">The zero-based index in <paramref name="array"/> at which copying begins.</param>
 171        /// <exception cref="ArgumentNullException">
 172        ///   <paramref name="array"/> is <see langword="null"/>.
 173        /// </exception>
 174        /// <exception cref="ArgumentOutOfRangeException">
 175        ///   <paramref name="index"/> is less than 0.
 176        /// </exception>
 177        /// <exception cref="ArgumentException">
 178        ///   The number of elements in the source ICollection is greater than the available space from <paramref name="
 179        ///   to the end of the destination <paramref name="array"/>.
 180        /// </exception>
 181        void ICollection<KeyValuePair<string, JsonNode?>>.CopyTo(KeyValuePair<string, JsonNode?>[] array, int index) =>
 0182            ((IDictionary<string, JsonNode?>)Dictionary).CopyTo(array, index);
 183
 184        /// <summary>
 185        ///   Returns an enumerator that iterates through the <see cref="JsonObject"/>.
 186        /// </summary>
 187        /// <returns>
 188        ///   An enumerator that iterates through the <see cref="JsonObject"/>.
 189        /// </returns>
 0190        public IEnumerator<KeyValuePair<string, JsonNode?>> GetEnumerator() => Dictionary.GetEnumerator();
 191
 192        /// <summary>
 193        ///   Removes a key and value from the <see cref="JsonObject"/>.
 194        /// </summary>
 195        /// <param name="item">
 196        ///   The KeyValuePair structure representing the property name and value to remove from the <see cref="JsonObje
 197        /// </param>
 198        /// <returns>
 199        ///   <see langword="true"/> if the element is successfully removed; otherwise, <see langword="false"/>.
 200        /// </returns>
 0201        bool ICollection<KeyValuePair<string, JsonNode?>>.Remove(KeyValuePair<string, JsonNode?> item) => Remove(item.Ke
 202
 203        /// <summary>
 204        ///   Gets a collection containing the property names in the <see cref="JsonObject"/>.
 205        /// </summary>
 0206        ICollection<string> IDictionary<string, JsonNode?>.Keys => Dictionary.Keys;
 207
 208        /// <summary>
 209        ///   Gets a collection containing the property values in the <see cref="JsonObject"/>.
 210        /// </summary>
 0211        ICollection<JsonNode?> IDictionary<string, JsonNode?>.Values => Dictionary.Values;
 212
 213        /// <summary>
 214        ///   Gets the value associated with the specified property name.
 215        /// </summary>
 216        /// <param name="propertyName">The property name of the value to get.</param>
 217        /// <param name="jsonNode">
 218        ///   When this method returns, contains the value associated with the specified property name, if the property 
 219        ///   otherwise, <see langword="null"/>.
 220        /// </param>
 221        /// <returns>
 222        ///   <see langword="true"/> if the <see cref="JsonObject"/> contains an element with the specified property nam
 223        /// </returns>
 224        /// <exception cref="ArgumentNullException">
 225        ///   <paramref name="propertyName"/> is <see langword="null"/>.
 226        /// </exception>
 227        bool IDictionary<string, JsonNode?>.TryGetValue(string propertyName, out JsonNode? jsonNode)
 0228        {
 0229            ArgumentNullException.ThrowIfNull(propertyName);
 230
 0231            return Dictionary.TryGetValue(propertyName, out jsonNode);
 0232        }
 233
 234        /// <summary>
 235        ///   Returns <see langword="false"/>.
 236        /// </summary>
 0237        bool ICollection<KeyValuePair<string, JsonNode?>>.IsReadOnly => false;
 238
 239        /// <summary>
 240        ///   Returns an enumerator that iterates through the <see cref="JsonObject"/>.
 241        /// </summary>
 242        /// <returns>
 243        ///   An enumerator that iterates through the <see cref="JsonObject"/>.
 244        /// </returns>
 0245        IEnumerator IEnumerable.GetEnumerator() => Dictionary.GetEnumerator();
 246
 247        private OrderedDictionary<string, JsonNode?> InitializeDictionary()
 0248        {
 0249            GetUnderlyingRepresentation(out OrderedDictionary<string, JsonNode?>? dictionary, out JsonElement? jsonEleme
 250
 0251            if (dictionary is null)
 0252            {
 0253                OrderedDictionary<string, JsonNode?> newDictionary = CreateDictionary(Options);
 254
 0255                if (jsonElement.HasValue)
 0256                {
 0257                    foreach (JsonProperty jElementProperty in jsonElement.Value.EnumerateObject())
 0258                    {
 0259                        JsonNode? node = JsonNodeConverter.Create(jElementProperty.Value, Options);
 0260                        node?.Parent = this;
 261
 0262                        newDictionary.Add(jElementProperty.Name, node);
 0263                    }
 0264                }
 265
 266                // Ensure only one dictionary instance is published using CompareExchange
 0267                OrderedDictionary<string, JsonNode?>? exchangedDictionary = Interlocked.CompareExchange(ref _dictionary,
 0268                if (exchangedDictionary is null)
 0269                {
 270                    // We won the race and published our dictionary
 271                    // Ensure _jsonElement is written to after _dictionary
 0272                    _jsonElement = null;
 0273                    dictionary = newDictionary;
 0274                }
 275                else
 0276                {
 277                    // Another thread won the race, use their dictionary
 0278                    dictionary = exchangedDictionary;
 0279                }
 0280            }
 281
 0282            return dictionary;
 0283        }
 284
 285        private static OrderedDictionary<string, JsonNode?> CreateDictionary(JsonNodeOptions? options, int capacity = 0)
 0286        {
 0287            StringComparer comparer = options?.PropertyNameCaseInsensitive ?? false
 0288                ? StringComparer.OrdinalIgnoreCase
 0289                : StringComparer.Ordinal;
 290
 0291            return new(capacity, comparer);
 0292        }
 293
 294        /// <summary>
 295        /// Provides a coherent view of the underlying representation of the current node.
 296        /// The jsonElement value should be consumed if and only if dictionary value is null.
 297        /// </summary>
 298        private void GetUnderlyingRepresentation(out OrderedDictionary<string, JsonNode?>? dictionary, out JsonElement? 
 0299        {
 300            // Because JsonElement cannot be read atomically there might be torn reads,
 301            // however the order of read/write operations guarantees that that's only
 302            // possible if the value of _dictionary is non-null.
 0303            jsonElement = _jsonElement;
 0304            Interlocked.MemoryBarrier();
 0305            dictionary = _dictionary;
 0306        }
 307    }
 308}

C:\h\w\B31A098C\w\BB5A0A33\e\runtime-utils\Runner\runtime\src\libraries\System.Text.Json\src\System\Text\Json\Nodes\JsonObject.IList.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections;
 5using System.Collections.Generic;
 6
 7namespace System.Text.Json.Nodes
 8{
 9    public partial class JsonObject : IList<KeyValuePair<string, JsonNode?>>
 10    {
 11        /// <summary>Gets the property the specified index.</summary>
 12        /// <param name="index">The zero-based index of the pair to get.</param>
 13        /// <returns>The property at the specified index as a key/value pair.</returns>
 14        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than 0 or greater than or equ
 015        public KeyValuePair<string, JsonNode?> GetAt(int index) => Dictionary.GetAt(index);
 16
 17        /// <summary>Sets a new property at the specified index.</summary>
 18        /// <param name="index">The zero-based index of the property to set.</param>
 19        /// <param name="propertyName">The property name to store at the specified index.</param>
 20        /// <param name="value">The JSON value to store at the specified index.</param>
 21        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than 0 or greater than or equ
 22        /// <exception cref="ArgumentException"><paramref name="propertyName"/> is already specified in a different inde
 23        /// <exception cref="InvalidOperationException"><paramref name="value"/> already has a parent.</exception>
 24        public void SetAt(int index, string propertyName, JsonNode? value)
 025        {
 026            ArgumentNullException.ThrowIfNull(propertyName);
 27
 028            OrderedDictionary<string, JsonNode?> dictionary = Dictionary;
 029            KeyValuePair<string, JsonNode?> existing = dictionary.GetAt(index);
 030            dictionary.SetAt(index, propertyName, value);
 031            DetachParent(existing.Value);
 032            value?.AssignParent(this);
 033        }
 34
 35        /// <summary>Sets a new property value at the specified index.</summary>
 36        /// <param name="index">The zero-based index of the property to set.</param>
 37        /// <param name="value">The JSON value to store at the specified index.</param>
 38        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than 0 or greater than or equ
 39        /// <exception cref="InvalidOperationException"><paramref name="value"/> already has a parent.</exception>
 40        public void SetAt(int index, JsonNode? value)
 041        {
 042            OrderedDictionary<string, JsonNode?> dictionary = Dictionary;
 043            KeyValuePair<string, JsonNode?> existing = dictionary.GetAt(index);
 044            dictionary.SetAt(index, value);
 045            DetachParent(existing.Value);
 046            value?.AssignParent(this);
 047        }
 48
 49        /// <summary>Determines the index of a specific property name in the object.</summary>
 50        /// <param name="propertyName">The property name to locate.</param>
 51        /// <returns>The index of <paramref name="propertyName"/> if found; otherwise, -1.</returns>
 52        /// <exception cref="ArgumentNullException"><paramref name="propertyName"/> is null.</exception>
 53        public int IndexOf(string propertyName)
 054        {
 055            ArgumentNullException.ThrowIfNull(propertyName);
 56
 057            return Dictionary.IndexOf(propertyName);
 058        }
 59
 60        /// <summary>Inserts a property into the object at the specified index.</summary>
 61        /// <param name="index">The zero-based index at which the property should be inserted.</param>
 62        /// <param name="propertyName">The property name to insert.</param>
 63        /// <param name="value">The JSON value to insert.</param>
 64        /// <exception cref="ArgumentNullException"><paramref name="propertyName"/> is null.</exception>
 65        /// <exception cref="ArgumentException">An element with the same key already exists in the <see cref="JsonObject
 66        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than 0 or greater than <see c
 67        public void Insert(int index, string propertyName, JsonNode? value)
 068        {
 069            ArgumentNullException.ThrowIfNull(propertyName);
 70
 071            Dictionary.Insert(index, propertyName, value);
 072            value?.AssignParent(this);
 073        }
 74
 75        /// <summary>Removes the property at the specified index.</summary>
 76        /// <param name="index">The zero-based index of the item to remove.</param>
 77        /// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is less than 0 or greater than or equ
 78        public void RemoveAt(int index)
 079        {
 080            KeyValuePair<string, JsonNode?> existing = Dictionary.GetAt(index);
 081            Dictionary.RemoveAt(index);
 082            DetachParent(existing.Value);
 083        }
 84
 85        /// <inheritdoc />
 86        KeyValuePair<string, JsonNode?> IList<KeyValuePair<string, JsonNode?>>.this[int index]
 87        {
 088            get => GetAt(index);
 089            set => SetAt(index, value.Key, value.Value);
 90        }
 91
 92        /// <inheritdoc />
 093        int IList<KeyValuePair<string, JsonNode?>>.IndexOf(KeyValuePair<string, JsonNode?> item) => ((IList<KeyValuePair
 94
 95        /// <inheritdoc />
 096        void IList<KeyValuePair<string, JsonNode?>>.Insert(int index, KeyValuePair<string, JsonNode?> item) => Insert(in
 97
 98        /// <inheritdoc />
 099        void IList<KeyValuePair<string, JsonNode?>>.RemoveAt(int index) => RemoveAt(index);
 100    }
 101}

Methods/Properties

UnderlyingElement()
.ctor(System.Nullable`1<System.Text.Json.Nodes.JsonNodeOptions>)
.ctor(System.Collections.Generic.IEnumerable`1<System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>>,System.Nullable`1<System.Text.Json.Nodes.JsonNodeOptions>)
Create(System.Text.Json.JsonElement,System.Nullable`1<System.Text.Json.Nodes.JsonNodeOptions>)
.ctor(System.Text.Json.JsonElement,System.Nullable`1<System.Text.Json.Nodes.JsonNodeOptions>)
Dictionary()
GetItem(System.Int32)
SetItem(System.Int32,System.Text.Json.Nodes.JsonNode)
DeepCloneCore()
GetPropertyName(System.Text.Json.Nodes.JsonNode)
TryGetPropertyValue(System.String,System.Text.Json.Nodes.JsonNode&)
TryGetPropertyValue(System.String,System.Text.Json.Nodes.JsonNode&,System.Int32&)
WriteTo(System.Text.Json.Utf8JsonWriter,System.Text.Json.JsonSerializerOptions)
WriteContentsTo(System.Text.Json.Utf8JsonWriter,System.Text.Json.JsonSerializerOptions)
GetValueKindCore()
DeepEqualsCore(System.Text.Json.Nodes.JsonNode)
GetItem(System.String)
GetPath(System.Text.ValueStringBuilder&,System.Text.Json.Nodes.JsonNode)
SetItem(System.String,System.Text.Json.Nodes.JsonNode)
DetachParent(System.Text.Json.Nodes.JsonNode)
FindValue(System.Text.Json.Nodes.JsonNode)
Add(System.String,System.Text.Json.Nodes.JsonNode)
TryAdd(System.String,System.Text.Json.Nodes.JsonNode)
TryAdd(System.String,System.Text.Json.Nodes.JsonNode,System.Int32&)
Add(System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>)
Clear()
ContainsKey(System.String)
Count()
Remove(System.String)
System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.Contains(System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>)
System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.CopyTo(System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>[],System.Int32)
GetEnumerator()
System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.Remove(System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>)
em.Collections.Generic.IDictionary<System.String,System.Text.Json.Nodes.JsonNode>.get_Keys()
em.Collections.Generic.IDictionary<System.String,System.Text.Json.Nodes.JsonNode>.get_Values()
System.Collections.Generic.IDictionary<System.String,System.Text.Json.Nodes.JsonNode>.TryGetValue(System.String,System.Text.Json.Nodes.JsonNode&)
em.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.get_IsReadOnly()
System.Collections.IEnumerable.GetEnumerator()
InitializeDictionary()
CreateDictionary(System.Nullable`1<System.Text.Json.Nodes.JsonNodeOptions>,System.Int32)
GetUnderlyingRepresentation(System.Collections.Generic.OrderedDictionary`2<System.String,System.Text.Json.Nodes.JsonNode>&,System.Nullable`1<System.Text.Json.JsonElement>&)
GetAt(System.Int32)
SetAt(System.Int32,System.String,System.Text.Json.Nodes.JsonNode)
SetAt(System.Int32,System.Text.Json.Nodes.JsonNode)
IndexOf(System.String)
Insert(System.Int32,System.String,System.Text.Json.Nodes.JsonNode)
RemoveAt(System.Int32)
em.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.get_Item(System.Int32)
em.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.set_Item(System.Int32,System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>)
System.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.IndexOf(System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>)
System.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.Insert(System.Int32,System.Collections.Generic.KeyValuePair`2<System.String,System.Text.Json.Nodes.JsonNode>)
System.Collections.Generic.IList<System.Collections.Generic.KeyValuePair<System.String,System.Text.Json.Nodes.JsonNode>>.RemoveAt(System.Int32)