From 60ca154c6f2ec85b59d3fc021206d08992a8b2de Mon Sep 17 00:00:00 2001 From: Loretta Date: Sat, 3 Jan 2026 08:34:49 +0100 Subject: [PATCH] Refactor JSON/Binary context & metadata class structure Renamed and split internal context and metadata classes for JSON and binary serialization/deserialization. - Replaced CrossTypeDeserializerBase with DeserializeCrossTypeBase; updated all usages. - Renamed DeserializationContextPool to JsonDeserializationContextPool; SerializationContextPool now uses JsonSerializationContext. - Renamed DeserializeTypeMetadata to JsonDeserializeTypeMetadata; TypeMetadata to JsonTypeMetadata, each in their own files. - Updated all method signatures and internal references to use new names. - Simplified BinaryDeserializeTypeMetadata by removing internal property dictionary. No changes to public APIs; improves code clarity and maintainability. --- ...erializer.BinaryDeserializeTypeMetadata.cs | 10 ------- .../AcBinaryDeserializer.CrossType.cs | 12 ++++----- ...zerBase.cs => DeserializeCrossTypeBase.cs} | 2 +- ...eserializer.JsonDeserializationContext.cs} | 2 +- ...serializer.JsonDeserializeTypeMetadata.cs} | 10 +++---- .../Jsons/AcJsonDeserializer.JsonElement.cs | 8 +++--- .../Jsons/AcJsonDeserializer.Utf8Reader.cs | 8 +++--- .../Serializers/Jsons/AcJsonDeserializer.cs | 26 +++++++++---------- ...sonSerializer.JsonSerializationContext.cs} | 12 ++++----- ...s => AcJsonSerializer.JsonTypeMetadata.cs} | 10 +++---- .../Serializers/Jsons/AcJsonSerializer.cs | 10 +++---- 11 files changed, 50 insertions(+), 60 deletions(-) rename AyCode.Core/Serializers/{CrossTypeDeserializerBase.cs => DeserializeCrossTypeBase.cs} (97%) rename AyCode.Core/Serializers/Jsons/{AcJsonDeserializer.DeserializationContext.cs => AcJsonDeserializer.JsonDeserializationContext.cs} (98%) rename AyCode.Core/Serializers/Jsons/{AcJsonDeserializer.DeserializeTypeMetadata.cs => AcJsonDeserializer.JsonDeserializeTypeMetadata.cs} (92%) rename AyCode.Core/Serializers/Jsons/{AcJsonSerializer.SerializationContext.cs => AcJsonSerializer.JsonSerializationContext.cs} (86%) rename AyCode.Core/Serializers/Jsons/{AcJsonSerializer.TypeMetadata.cs => AcJsonSerializer.JsonTypeMetadata.cs} (69%) diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs index 92550e2..2168139 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializeTypeMetadata.cs @@ -10,8 +10,6 @@ public static partial class AcBinaryDeserializer { internal sealed class BinaryDeserializeTypeMetadata : BinaryTypeMetadataBase { - private readonly FrozenDictionary _properties; - /// /// Properties array ordered alphabetically by name for index-based lookup. /// This matches the serializer's ordering, enabling O(1) array access. @@ -27,10 +25,6 @@ public static partial class AcBinaryDeserializer { PropertiesArray[i] = new BinaryPropertySetterInfo(orderedProperties[i], type); } - - _properties = PropertiesArray.Length == 0 - ? FrozenDictionary.Empty - : PropertiesArray.ToFrozenDictionary(static p => p.Name, static p => p, StringComparer.Ordinal); } /// @@ -39,10 +33,6 @@ public static partial class AcBinaryDeserializer [MethodImpl(MethodImplOptions.AggressiveInlining)] public BinaryPropertySetterInfo? GetPropertyByIndex(int index) => (uint)index < (uint)PropertiesArray.Length ? PropertiesArray[index] : null; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetProperty(string name, out BinaryPropertySetterInfo? propertyInfo) - => _properties.TryGetValue(name, out propertyInfo); } /// diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs index fb85666..cd61bd8 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.CrossType.cs @@ -14,7 +14,7 @@ public static partial class AcBinaryDeserializer /// [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int[] GetIndexMapping(Type sourceType, Type destType, PropertyMapperDelegate? customMapper) - => IndexMappingCache.GetOrBuild(sourceType, destType, customMapper, CrossTypeDeserializerBase.GetOrderedProperties); + => IndexMappingCache.GetOrBuild(sourceType, destType, customMapper, DeserializeCrossTypeBase.GetOrderedProperties); #region Cross-Type Deserialization @@ -42,14 +42,14 @@ public static partial class AcBinaryDeserializer public static TDest? Deserialize(ReadOnlySpan data, AcBinarySerializerOptions options) { // Early exit checks - if (CrossTypeDeserializerBase.IsEmptyData(data, BinaryTypeCode.Null)) + if (DeserializeCrossTypeBase.IsEmptyData(data, BinaryTypeCode.Null)) return default; var sourceType = typeof(TSource); var destType = typeof(TDest); // Fast path: same type - if (CrossTypeDeserializerBase.IsSameType(sourceType, destType)) + if (DeserializeCrossTypeBase.IsSameType(sourceType, destType)) return Deserialize(data, options); // Cross-type path: use index mapping @@ -117,17 +117,17 @@ public static partial class AcBinaryDeserializer where TDest : class { // Validation - CrossTypeDeserializerBase.ValidatePopulateTarget(target); + DeserializeCrossTypeBase.ValidatePopulateTarget(target); // Early exit checks - if (CrossTypeDeserializerBase.IsEmptyData(data, BinaryTypeCode.Null)) + if (DeserializeCrossTypeBase.IsEmptyData(data, BinaryTypeCode.Null)) return; var sourceType = typeof(TSource); var destType = typeof(TDest); // Fast path: same type - if (CrossTypeDeserializerBase.IsSameType(sourceType, destType)) + if (DeserializeCrossTypeBase.IsSameType(sourceType, destType)) { Populate(data, target, options); return; diff --git a/AyCode.Core/Serializers/CrossTypeDeserializerBase.cs b/AyCode.Core/Serializers/DeserializeCrossTypeBase.cs similarity index 97% rename from AyCode.Core/Serializers/CrossTypeDeserializerBase.cs rename to AyCode.Core/Serializers/DeserializeCrossTypeBase.cs index 79f0767..b1abb2b 100644 --- a/AyCode.Core/Serializers/CrossTypeDeserializerBase.cs +++ b/AyCode.Core/Serializers/DeserializeCrossTypeBase.cs @@ -8,7 +8,7 @@ namespace AyCode.Core.Serializers; /// Utility class providing common cross-type deserialization functionality. /// Shared by both JSON and Binary deserializers. /// -public static class CrossTypeDeserializerBase +public static class DeserializeCrossTypeBase { /// /// Gets ordered properties for a type using stable PropertyIndex ordering. diff --git a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.DeserializationContext.cs b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializationContext.cs similarity index 98% rename from AyCode.Core/Serializers/Jsons/AcJsonDeserializer.DeserializationContext.cs rename to AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializationContext.cs index ae2402d..b66b9aa 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.DeserializationContext.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializationContext.cs @@ -5,7 +5,7 @@ namespace AyCode.Core.Serializers.Jsons; public static partial class AcJsonDeserializer { - private static class DeserializationContextPool + private static class JsonDeserializationContextPool { private static readonly ConcurrentQueue Pool = new(); private const int MaxPoolSize = 16; diff --git a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.DeserializeTypeMetadata.cs b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializeTypeMetadata.cs similarity index 92% rename from AyCode.Core/Serializers/Jsons/AcJsonDeserializer.DeserializeTypeMetadata.cs rename to AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializeTypeMetadata.cs index 70a39d4..fdfc387 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.DeserializeTypeMetadata.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonDeserializeTypeMetadata.cs @@ -9,22 +9,22 @@ namespace AyCode.Core.Serializers.Jsons; public static partial class AcJsonDeserializer { - private static readonly ConcurrentDictionary TypeMetadataCache = new(); + private static readonly ConcurrentDictionary TypeMetadataCache = new(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static DeserializeTypeMetadata GetTypeMetadata(in Type type) - => TypeMetadataCache.GetOrAdd(type, static t => new DeserializeTypeMetadata(t)); + private static JsonDeserializeTypeMetadata GetTypeMetadata(in Type type) + => TypeMetadataCache.GetOrAdd(type, static t => new JsonDeserializeTypeMetadata(t)); /// /// JSON deserialization type metadata. /// Extends DeserializeTypeMetadataBase which provides cached IId info. /// - private sealed class DeserializeTypeMetadata : DeserializeTypeMetadataBase + private sealed class JsonDeserializeTypeMetadata : DeserializeTypeMetadataBase { public FrozenDictionary PropertySettersFrozen { get; } public PropertySetterInfo[] PropertiesArray { get; } // Array for fast UTF8 linear scan (small objects) - public DeserializeTypeMetadata(Type type) : base(type) + public JsonDeserializeTypeMetadata(Type type) : base(type) { var props = GetSerializableProperties(type, requiresRead: true, requiresWrite: true).ToList(); diff --git a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonElement.cs b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonElement.cs index a1c5f7d..3522569 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonElement.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.JsonElement.cs @@ -110,7 +110,7 @@ public static partial class AcJsonDeserializer /// /// Copies properties from source to target using JSON metadata. /// - private static void CopyPropertiesJson(object source, object target, DeserializeTypeMetadata metadata) + private static void CopyPropertiesJson(object source, object target, JsonDeserializeTypeMetadata metadata) { foreach (var prop in metadata.PropertiesArray) { @@ -120,7 +120,7 @@ public static partial class AcJsonDeserializer } } - private static void PopulateObjectInternal(in JsonElement element, object target, DeserializeTypeMetadata metadata, DeserializationContext context, int depth) + private static void PopulateObjectInternal(in JsonElement element, object target, JsonDeserializeTypeMetadata metadata, DeserializationContext context, int depth) { var propsDict = metadata.PropertySettersFrozen; var nextDepth = depth + 1; @@ -143,7 +143,7 @@ public static partial class AcJsonDeserializer } } - private static void PopulateObjectInternalMerge(in JsonElement element, object target, DeserializeTypeMetadata metadata, DeserializationContext context, int depth) + private static void PopulateObjectInternalMerge(in JsonElement element, object target, JsonDeserializeTypeMetadata metadata, DeserializationContext context, int depth) { var propsDict = metadata.PropertySettersFrozen; var nextDepth = depth + 1; @@ -234,7 +234,7 @@ public static partial class AcJsonDeserializer var nextDepth = depth + 1; // ChainMode: Use cached IId info from element type metadata (no runtime reflection!) - DeserializeTypeMetadata? elementMetadata = null; + JsonDeserializeTypeMetadata? elementMetadata = null; if (context.IsChainMode && !IsPrimitiveOrStringFast(elementType)) { elementMetadata = GetTypeMetadata(elementType); diff --git a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.Utf8Reader.cs b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.Utf8Reader.cs index 3375f14..d2a4657 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.Utf8Reader.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.Utf8Reader.cs @@ -255,7 +255,7 @@ public static partial class AcJsonDeserializer /// /// Read object from reader when we're already at StartObject. /// - private static object? ReadObjectFromReaderAtStart(ref Utf8JsonReader reader, Type targetType, DeserializeTypeMetadata metadata, byte maxDepth, int depth) + private static object? ReadObjectFromReaderAtStart(ref Utf8JsonReader reader, Type targetType, JsonDeserializeTypeMetadata metadata, byte maxDepth, int depth) { if (depth > maxDepth) { @@ -380,7 +380,7 @@ public static partial class AcJsonDeserializer /// /// Populate object using Utf8JsonReader streaming (no DOM allocation). /// - private static void PopulateObjectWithUtf8Reader(string json, object target, DeserializeTypeMetadata metadata, byte maxDepth) + private static void PopulateObjectWithUtf8Reader(string json, object target, JsonDeserializeTypeMetadata metadata, byte maxDepth) { var (buffer, length) = GetUtf8Bytes(json); try @@ -442,7 +442,7 @@ public static partial class AcJsonDeserializer /// /// Populate object with merge semantics from Utf8JsonReader. /// - private static void PopulateObjectMergeFromReader(ref Utf8JsonReader reader, object target, DeserializeTypeMetadata metadata, byte maxDepth, int depth) + private static void PopulateObjectMergeFromReader(ref Utf8JsonReader reader, object target, JsonDeserializeTypeMetadata metadata, byte maxDepth, int depth) { var nextDepth = depth + 1; var maxDepthReached = nextDepth > maxDepth; @@ -607,7 +607,7 @@ public static partial class AcJsonDeserializer /// /// Copy properties from source to target using metadata. /// - private static void CopyProperties(object source, object target, DeserializeTypeMetadata metadata) + private static void CopyProperties(object source, object target, JsonDeserializeTypeMetadata metadata) { foreach (var prop in metadata.PropertySettersFrozen.Values) { diff --git a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.cs b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.cs index 3c7ce0a..f1e78d4 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonDeserializer.cs @@ -76,7 +76,7 @@ public static partial class AcJsonDeserializer var jsonBytes = utf8Json.ToArray(); using var doc = JsonDocument.Parse(jsonBytes); - var context = DeserializationContextPool.Get(options); + var context = JsonDeserializationContextPool.Get(options); try { var result = ReadValue(doc.RootElement, targetType, context, 0); @@ -85,7 +85,7 @@ public static partial class AcJsonDeserializer } finally { - DeserializationContextPool.Return(context); + JsonDeserializationContextPool.Return(context); } } catch (AcJsonDeserializationException) { throw; } @@ -135,7 +135,7 @@ public static partial class AcJsonDeserializer } using var doc = JsonDocument.Parse(json); - var context = DeserializationContextPool.Get(options); + var context = JsonDeserializationContextPool.Get(options); try { var result = ReadValue(doc.RootElement, targetType, context, 0); @@ -144,7 +144,7 @@ public static partial class AcJsonDeserializer } finally { - DeserializationContextPool.Return(context); + JsonDeserializationContextPool.Return(context); } } catch (AcJsonDeserializationException) { throw; } @@ -202,7 +202,7 @@ public static partial class AcJsonDeserializer // Reference handling requires DOM - copy to array for JsonDocument.Parse var jsonBytes = Encoding.UTF8.GetBytes(json); using var doc = JsonDocument.Parse(jsonBytes); - var context = DeserializationContextPool.Get(options); + var context = JsonDeserializationContextPool.Get(options); try { var result = ReadValue(doc.RootElement, targetType, context, 0); @@ -211,7 +211,7 @@ public static partial class AcJsonDeserializer } finally { - DeserializationContextPool.Return(context); + JsonDeserializationContextPool.Return(context); } } catch (AcJsonDeserializationException) { throw; } @@ -287,7 +287,7 @@ public static partial class AcJsonDeserializer // Reference handling requires DOM - copy to array for JsonDocument.Parse var jsonBytes = utf8Json.ToArray(); using var doc = JsonDocument.Parse(jsonBytes); - var context = DeserializationContextPool.Get(options); + var context = JsonDeserializationContextPool.Get(options); try { var result = ReadValue(doc.RootElement, targetType, context, 0); @@ -296,7 +296,7 @@ public static partial class AcJsonDeserializer } finally { - DeserializationContextPool.Return(context); + JsonDeserializationContextPool.Return(context); } } catch (AcJsonDeserializationException) { throw; } @@ -398,7 +398,7 @@ public static partial class AcJsonDeserializer using var doc = JsonDocument.Parse(json); var rootElement = doc.RootElement; - var context = DeserializationContextPool.Get(options); + var context = JsonDeserializationContextPool.Get(options); context.IsMergeMode = true; try @@ -426,7 +426,7 @@ public static partial class AcJsonDeserializer } finally { - DeserializationContextPool.Return(context); + JsonDeserializationContextPool.Return(context); } } catch (AcJsonDeserializationException) { throw; } @@ -505,7 +505,7 @@ public static partial class AcJsonDeserializer var doc = JsonDocument.Parse(json); var chainTracker = new AcSerializerCommon.ChainReferenceTracker(); - var context = DeserializationContextPool.Get(options); + var context = JsonDeserializationContextPool.Get(options); context.ChainTracker = chainTracker; try @@ -516,7 +516,7 @@ public static partial class AcJsonDeserializer } catch { - DeserializationContextPool.Return(context); + JsonDeserializationContextPool.Return(context); doc.Dispose(); throw; } @@ -629,7 +629,7 @@ public static partial class AcJsonDeserializer if (_context != null) { - DeserializationContextPool.Return(_context); + JsonDeserializationContextPool.Return(_context); _context = null; } _document?.Dispose(); diff --git a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.SerializationContext.cs b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonSerializationContext.cs similarity index 86% rename from AyCode.Core/Serializers/Jsons/AcJsonSerializer.SerializationContext.cs rename to AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonSerializationContext.cs index 5d8852b..95e25df 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.SerializationContext.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonSerializationContext.cs @@ -10,22 +10,22 @@ public static partial class AcJsonSerializer { private static class SerializationContextPool { - private static readonly ConcurrentQueue Pool = new(); + private static readonly ConcurrentQueue Pool = new(); private const int MaxPoolSize = 16; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SerializationContext Get(in AcJsonSerializerOptions options) + public static JsonSerializationContext Get(in AcJsonSerializerOptions options) { if (Pool.TryDequeue(out var context)) { context.Reset(options); return context; } - return new SerializationContext(options); + return new JsonSerializationContext(options); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Return(SerializationContext context) + public static void Return(JsonSerializationContext context) { if (Pool.Count < MaxPoolSize) { @@ -35,7 +35,7 @@ public static partial class AcJsonSerializer } } - private sealed class SerializationContext : IDisposable + private sealed class JsonSerializationContext : IDisposable { private readonly ArrayBufferWriter _buffer; public Utf8JsonWriter Writer { get; private set; } @@ -52,7 +52,7 @@ public static partial class AcJsonSerializer SkipValidation = true // Skip validation for performance }; - public SerializationContext(in AcJsonSerializerOptions options) + public JsonSerializationContext(in AcJsonSerializerOptions options) { _buffer = new ArrayBufferWriter(4096); Writer = new Utf8JsonWriter(_buffer, WriterOptions); diff --git a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.TypeMetadata.cs b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonTypeMetadata.cs similarity index 69% rename from AyCode.Core/Serializers/Jsons/AcJsonSerializer.TypeMetadata.cs rename to AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonTypeMetadata.cs index ae72e7f..2e1cc7f 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.TypeMetadata.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.JsonTypeMetadata.cs @@ -7,17 +7,17 @@ namespace AyCode.Core.Serializers.Jsons; public static partial class AcJsonSerializer { - private static readonly ConcurrentDictionary TypeMetadataCache = new(); + private static readonly ConcurrentDictionary TypeMetadataCache = new(); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static TypeMetadata GetTypeMetadata(in Type type) - => TypeMetadataCache.GetOrAdd(type, static t => new TypeMetadata(t)); + private static JsonTypeMetadata GetTypeMetadata(in Type type) + => TypeMetadataCache.GetOrAdd(type, static t => new JsonTypeMetadata(t)); - private sealed class TypeMetadata : TypeMetadataBase + private sealed class JsonTypeMetadata : TypeMetadataBase { public PropertyAccessor[] Properties { get; } - public TypeMetadata(Type type) : base(type) + public JsonTypeMetadata(Type type) : base(type) { Properties = GetSerializableProperties(type, requiresRead: true, requiresWrite: false) .Select(p => new PropertyAccessor(p, type)) diff --git a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.cs b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.cs index adf17ed..2583bbc 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonSerializer.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonSerializer.cs @@ -121,7 +121,7 @@ public static partial class AcJsonSerializer #region Reference Scanning - private static void ScanReferences(object? value, SerializationContext context, int depth) + private static void ScanReferences(object? value, JsonSerializationContext context, int depth) { if (value == null || depth > context.MaxDepth) return; @@ -150,7 +150,7 @@ public static partial class AcJsonSerializer #region Serialization - private static void WriteValue(object? value, SerializationContext context, int depth) + private static void WriteValue(object? value, JsonSerializationContext context, int depth) { if (value == null) { context.Writer.WriteNullValue(); return; } @@ -167,7 +167,7 @@ public static partial class AcJsonSerializer } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteObject(object value, in Type type, SerializationContext context, int depth) + private static void WriteObject(object value, in Type type, JsonSerializationContext context, int depth) { var writer = context.Writer; @@ -207,7 +207,7 @@ public static partial class AcJsonSerializer } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteArray(IEnumerable enumerable, SerializationContext context, int depth) + private static void WriteArray(IEnumerable enumerable, JsonSerializationContext context, int depth) { var writer = context.Writer; writer.WriteStartArray(); @@ -222,7 +222,7 @@ public static partial class AcJsonSerializer } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteDictionary(IDictionary dictionary, SerializationContext context, int depth) + private static void WriteDictionary(IDictionary dictionary, JsonSerializationContext context, int depth) { var writer = context.Writer; writer.WriteStartObject();