@@ -91,30 +91,88 @@ protected override void GenerateSerializer(ITypeSymbol typeSymbol, Writer writer
9191 writer . AppendLine ( " int cnt = value.Count;" ) ;
9292 writer . AppendLine ( " writer.Write(TypeCollector.GetCollectionHeader(cnt));" ) ;
9393 writer . AppendLine ( ) ;
94- writer . AppendLine ( " foreach (var item in value)" ) ;
95- writer . AppendLine ( " {" ) ;
9694
97- if ( kvpIsUnmanaged )
95+ var originalDef = namedType . OriginalDefinition . ToDisplayString ( ) ;
96+ bool isDictionary = originalDef == "System.Collections.Generic.Dictionary<TKey, TValue>" ;
97+
98+ if ( isDictionary )
9899 {
99- // For unmanaged KVP, use UnsafeWrite directly (no WeakVersionTolerance needed)
100- writer . AppendLine ( " writer.UnsafeWrite(item);" ) ;
100+ var dictViewTypeName = $ "TypeCollector.DictionaryView<{ keyType . GetDisplayString ( ) } , { valueType . GetDisplayString ( ) } >";
101+ writer . Append ( " ref var dict = ref System.Runtime.CompilerServices.Unsafe.As<" ) ;
102+ writer . Append ( typeName ) ;
103+ writer . Append ( ", " ) ;
104+ writer . Append ( dictViewTypeName ) ;
105+ writer . AppendLine ( ">(ref value);" ) ;
106+ writer . AppendLine ( " var entries = dict._entries;" ) ;
107+ writer . AppendLine ( " if (entries == null)" ) ;
108+ writer . AppendLine ( " {" ) ;
109+ writer . AppendLine ( " return;" ) ;
110+ writer . AppendLine ( " }" ) ;
111+ writer . AppendLine ( " int count = dict._count;" ) ;
112+ writer . AppendLine ( " // Iterate entries via direct ref to avoid bounds checks" ) ;
113+ writer . AppendLine ( " ref var entryRef = ref System.Runtime.InteropServices.MemoryMarshal.GetArrayDataReference(entries);" ) ;
114+ writer . AppendLine ( " int index = 0;" ) ;
115+ writer . AppendLine ( " while ((uint)index < (uint)count)" ) ;
116+ writer . AppendLine ( " {" ) ;
117+ writer . AppendLine ( " ref var entry = ref System.Runtime.CompilerServices.Unsafe.Add(ref entryRef, index++);" ) ;
118+ writer . AppendLine ( " if (entry.next < -1)" ) ;
119+ writer . AppendLine ( " {" ) ;
120+ writer . AppendLine ( " continue;" ) ;
121+ writer . AppendLine ( " }" ) ;
122+
123+ if ( kvpIsUnmanaged )
124+ {
125+ writer . Append ( " var kvp = new System.Collections.Generic.KeyValuePair<" ) ;
126+ writer . Append ( keyType . GetDisplayString ( ) ) ;
127+ writer . Append ( ", " ) ;
128+ writer . Append ( valueType . GetDisplayString ( ) ) ;
129+ writer . AppendLine ( ">(entry.key, entry.value);" ) ;
130+ writer . AppendLine ( " writer.UnsafeWrite(kvp);" ) ;
131+ }
132+ else
133+ {
134+ // For managed KVP, serialize Key and Value separately with WeakVersionTolerance
135+ IfDirective ( NinoTypeHelper . WeakVersionToleranceSymbol , writer ,
136+ w => { w . AppendLine ( " var pos = writer.Advance(4);" ) ; } ) ;
137+
138+ writer . Append ( " " ) ;
139+ writer . AppendLine ( GetSerializeString ( keyType , "entry.key" ) ) ;
140+ writer . Append ( " " ) ;
141+ writer . AppendLine ( GetSerializeString ( valueType , "entry.value" ) ) ;
142+
143+ IfDirective ( NinoTypeHelper . WeakVersionToleranceSymbol , writer ,
144+ w => { w . AppendLine ( " writer.PutLength(pos);" ) ; } ) ;
145+ }
146+
147+ writer . AppendLine ( " }" ) ;
101148 }
102149 else
103150 {
104- // For managed KVP, serialize Key and Value separately with WeakVersionTolerance
105- IfDirective ( NinoTypeHelper . WeakVersionToleranceSymbol , writer ,
106- w => { w . AppendLine ( " var pos = writer.Advance(4);" ) ; } ) ;
151+ writer . AppendLine ( " foreach (var item in value)" ) ;
152+ writer . AppendLine ( " {" ) ;
107153
108- writer . Append ( " " ) ;
109- writer . AppendLine ( GetSerializeString ( keyType , "item.Key" ) ) ;
110- writer . Append ( " " ) ;
111- writer . AppendLine ( GetSerializeString ( valueType , "item.Value" ) ) ;
154+ if ( kvpIsUnmanaged )
155+ {
156+ // For unmanaged KVP, use UnsafeWrite directly (no WeakVersionTolerance needed)
157+ writer . AppendLine ( " writer.UnsafeWrite(item);" ) ;
158+ }
159+ else
160+ {
161+ // For managed KVP, serialize Key and Value separately with WeakVersionTolerance
162+ IfDirective ( NinoTypeHelper . WeakVersionToleranceSymbol , writer ,
163+ w => { w . AppendLine ( " var pos = writer.Advance(4);" ) ; } ) ;
112164
113- IfDirective ( NinoTypeHelper . WeakVersionToleranceSymbol , writer ,
114- w => { w . AppendLine ( " writer.PutLength(pos);" ) ; } ) ;
115- }
165+ writer . Append ( " " ) ;
166+ writer . AppendLine ( GetSerializeString ( keyType , "item.Key" ) ) ;
167+ writer . Append ( " " ) ;
168+ writer . AppendLine ( GetSerializeString ( valueType , "item.Value" ) ) ;
116169
117- writer . AppendLine ( " }" ) ;
170+ IfDirective ( NinoTypeHelper . WeakVersionToleranceSymbol , writer ,
171+ w => { w . AppendLine ( " writer.PutLength(pos);" ) ; } ) ;
172+ }
173+
174+ writer . AppendLine ( " }" ) ;
175+ }
118176
119177 writer . AppendLine ( "}" ) ;
120178 }
0 commit comments