@@ -63,8 +63,18 @@ public override object Deserialize(
63
63
bsonReader . ReadNull ( ) ;
64
64
return null ;
65
65
case BsonType . Array :
66
+ var itemNominalType = typeof ( T ) ;
67
+ var itemNominalTypeIsValueType = itemNominalType . IsValueType ;
68
+ var itemNominalTypeSerializer = BsonSerializer . LookupSerializer ( itemNominalType ) ;
69
+ var itemDiscriminatorConvention = BsonSerializer . LookupDiscriminatorConvention ( itemNominalType ) ;
70
+ Type lastItemType = null ;
71
+ IBsonSerializer lastItemSerializer = null ;
72
+
73
+ // if itemNominalType is a value type then these assignments are final
74
+ var itemActualType = itemNominalType ;
75
+ var itemActualTypeSerializer = itemNominalTypeSerializer ;
76
+
66
77
bsonReader . ReadStartArray ( ) ;
67
- var discriminatorConvention = BsonSerializer . LookupDiscriminatorConvention ( typeof ( T ) ) ;
68
78
var outerList = new List < List < List < T > > > ( ) ;
69
79
while ( bsonReader . ReadBsonType ( ) != BsonType . EndOfDocument )
70
80
{
@@ -76,10 +86,26 @@ public override object Deserialize(
76
86
var innerList = new List < T > ( ) ;
77
87
while ( bsonReader . ReadBsonType ( ) != BsonType . EndOfDocument )
78
88
{
79
- var elementType = discriminatorConvention . GetActualType ( bsonReader , typeof ( T ) ) ;
80
- var serializer = BsonSerializer . LookupSerializer ( elementType ) ;
81
- var element = ( T ) serializer . Deserialize ( bsonReader , typeof ( T ) , elementType , itemSerializationOptions ) ;
82
- innerList . Add ( element ) ;
89
+ if ( ! itemNominalTypeIsValueType )
90
+ {
91
+ itemActualType = itemDiscriminatorConvention . GetActualType ( bsonReader , itemNominalType ) ;
92
+ if ( itemActualType == itemNominalType )
93
+ {
94
+ itemActualTypeSerializer = itemNominalTypeSerializer ;
95
+ }
96
+ else if ( itemActualType == lastItemType )
97
+ {
98
+ itemActualTypeSerializer = lastItemSerializer ;
99
+ }
100
+ else
101
+ {
102
+ itemActualTypeSerializer = BsonSerializer . LookupSerializer ( itemActualType ) ;
103
+ lastItemType = itemActualType ;
104
+ lastItemSerializer = itemActualTypeSerializer ;
105
+ }
106
+ }
107
+ var item = ( T ) itemActualTypeSerializer . Deserialize ( bsonReader , itemNominalType , itemActualType , itemSerializationOptions ) ;
108
+ innerList . Add ( item ) ;
83
109
}
84
110
bsonReader . ReadEndArray ( ) ;
85
111
middleList . Add ( innerList ) ;
@@ -166,6 +192,17 @@ public override void Serialize(
166
192
var arraySerializationOptions = EnsureSerializationOptions < ArraySerializationOptions > ( options ) ;
167
193
var itemSerializationOptions = arraySerializationOptions . ItemSerializationOptions ;
168
194
195
+ var itemNominalType = typeof ( T ) ;
196
+ var itemNominalTypeIsValueType = itemNominalType . IsValueType ;
197
+ var itemNominalTypeSerializer = BsonSerializer . LookupSerializer ( itemNominalType ) ;
198
+ var itemDiscriminatorConvention = BsonSerializer . LookupDiscriminatorConvention ( itemNominalType ) ;
199
+ Type lastItemType = null ;
200
+ IBsonSerializer lastItemSerializer = null ;
201
+
202
+ // if itemNominalType is a value type then these assignments are final
203
+ var itemActualType = itemNominalType ;
204
+ var itemActualTypeSerializer = itemNominalTypeSerializer ;
205
+
169
206
bsonWriter . WriteStartArray ( ) ;
170
207
var length1 = array . GetLength ( 0 ) ;
171
208
var length2 = array . GetLength ( 1 ) ;
@@ -178,7 +215,26 @@ public override void Serialize(
178
215
bsonWriter . WriteStartArray ( ) ;
179
216
for ( int k = 0 ; k < length3 ; k ++ )
180
217
{
181
- BsonSerializer . Serialize ( bsonWriter , typeof ( T ) , array [ i , j , k ] , itemSerializationOptions ) ;
218
+ var item = array [ i , j , k ] ;
219
+ if ( ! itemNominalTypeIsValueType )
220
+ {
221
+ itemActualType = item == null ? itemNominalType : item . GetType ( ) ;
222
+ if ( itemActualType == itemNominalType )
223
+ {
224
+ itemActualTypeSerializer = itemNominalTypeSerializer ;
225
+ }
226
+ else if ( itemActualType == lastItemType )
227
+ {
228
+ itemActualTypeSerializer = lastItemSerializer ;
229
+ }
230
+ else
231
+ {
232
+ itemActualTypeSerializer = BsonSerializer . LookupSerializer ( itemActualType ) ;
233
+ lastItemType = itemActualType ;
234
+ lastItemSerializer = itemActualTypeSerializer ;
235
+ }
236
+ }
237
+ itemActualTypeSerializer . Serialize ( bsonWriter , itemNominalType , item , itemSerializationOptions ) ;
182
238
}
183
239
bsonWriter . WriteEndArray ( ) ;
184
240
}
0 commit comments