@@ -30,8 +30,6 @@ public class BsonClassMapSerializer<TClass> : SerializerBase<TClass>, IBsonIdPro
30
30
{
31
31
// private fields
32
32
private readonly BsonClassMap _classMap ;
33
- private readonly bool _isReferenceType ;
34
- private readonly bool _isValueType ;
35
33
36
34
// constructors
37
35
/// <summary>
@@ -42,21 +40,19 @@ public BsonClassMapSerializer(BsonClassMap classMap)
42
40
{
43
41
if ( classMap == null )
44
42
{
45
- throw new ArgumentNullException ( " classMap" ) ;
43
+ throw new ArgumentNullException ( nameof ( classMap ) ) ;
46
44
}
47
45
if ( classMap . ClassType != typeof ( TClass ) )
48
46
{
49
47
var message = string . Format ( "Must be a BsonClassMap for the type {0}." , typeof ( TClass ) ) ;
50
- throw new ArgumentException ( message , " classMap" ) ;
48
+ throw new ArgumentException ( message , nameof ( classMap ) ) ;
51
49
}
52
50
if ( ! classMap . IsFrozen )
53
51
{
54
52
throw new ArgumentException ( "Class map is not frozen." , nameof ( classMap ) ) ;
55
53
}
56
54
57
55
_classMap = classMap ;
58
- _isValueType = _classMap . ClassType . IsValueType ;
59
- _isReferenceType = ! _isValueType ;
60
56
}
61
57
62
58
// public properties
@@ -87,22 +83,17 @@ public override TClass Deserialize(BsonDeserializationContext context, BsonDeser
87
83
bsonReader . ReadNull ( ) ;
88
84
return default ( TClass ) ;
89
85
}
90
- else
91
- {
92
- var discriminatorConvention = _classMap . GetDiscriminatorConvention ( ) ;
93
86
94
- var actualType = discriminatorConvention . GetActualType ( bsonReader , args . NominalType ) ;
95
- if ( actualType == typeof ( TClass ) )
96
- {
97
- return DeserializeClass ( context ) ;
98
- }
99
- else
100
- {
101
- var serializer = BsonSerializer . LookupSerializer ( actualType ) ;
102
- return ( TClass ) serializer . Deserialize ( context ) ;
103
- }
87
+ var discriminatorConvention = _classMap . GetDiscriminatorConvention ( ) ;
104
88
89
+ var actualType = discriminatorConvention . GetActualType ( bsonReader , args . NominalType ) ;
90
+ if ( actualType == typeof ( TClass ) )
91
+ {
92
+ return DeserializeClass ( context ) ;
105
93
}
94
+
95
+ var serializer = BsonSerializer . LookupSerializer ( actualType ) ;
96
+ return ( TClass ) serializer . Deserialize ( context ) ;
106
97
}
107
98
108
99
/// <summary>
@@ -124,7 +115,9 @@ public TClass DeserializeClass(BsonDeserializationContext context)
124
115
}
125
116
126
117
Dictionary < string , object > values = null ;
127
- var document = default ( TClass ) ;
118
+ // Important for struct support:
119
+ // should use object variable here, so created value should be boxed right away!
120
+ object document = null ;
128
121
129
122
ISupportInitialize supportsInitialization = null ;
130
123
if ( _classMap . HasCreatorMaps )
@@ -135,13 +128,7 @@ public TClass DeserializeClass(BsonDeserializationContext context)
135
128
else
136
129
{
137
130
// for mutable classes we deserialize the values directly into the result object
138
- if ( _isValueType )
139
- {
140
- var message = string . Format ( "Value class {0} cannot be deserialized without a constructor." , _classMap . ClassType . FullName ) ;
141
- throw new BsonSerializationException ( message ) ;
142
- }
143
-
144
- document = ( TClass ) _classMap . CreateInstance ( ) ;
131
+ document = _classMap . CreateInstance ( ) ;
145
132
146
133
if ( document == null )
147
134
{
@@ -173,7 +160,7 @@ public TClass DeserializeClass(BsonDeserializationContext context)
173
160
var memberMap = allMemberMaps [ memberMapIndex ] ;
174
161
if ( memberMapIndex != extraElementsMemberMapIndex )
175
162
{
176
- if ( _isReferenceType && document != null )
163
+ if ( document != null )
177
164
{
178
165
if ( memberMap . IsReadOnly )
179
166
{
@@ -193,7 +180,7 @@ public TClass DeserializeClass(BsonDeserializationContext context)
193
180
}
194
181
else
195
182
{
196
- if ( _isReferenceType && document != null )
183
+ if ( document != null )
197
184
{
198
185
DeserializeExtraElementMember ( context , document , elementName , memberMap ) ;
199
186
}
@@ -215,7 +202,7 @@ public TClass DeserializeClass(BsonDeserializationContext context)
215
202
if ( extraElementsMemberMapIndex >= 0 )
216
203
{
217
204
var extraElementsMemberMap = _classMap . ExtraElementsMemberMap ;
218
- if ( _isReferenceType && document != null )
205
+ if ( document != null )
219
206
{
220
207
DeserializeExtraElementMember ( context , document , elementName , extraElementsMemberMap ) ;
221
208
}
@@ -267,7 +254,7 @@ public TClass DeserializeClass(BsonDeserializationContext context)
267
254
throw new FormatException ( message ) ;
268
255
}
269
256
270
- if ( _isReferenceType && document != null )
257
+ if ( document != null )
271
258
{
272
259
memberMap . ApplyDefaultValue ( document ) ;
273
260
}
@@ -289,18 +276,16 @@ public TClass DeserializeClass(BsonDeserializationContext context)
289
276
}
290
277
}
291
278
292
- if ( _isReferenceType && document != null )
279
+ if ( document != null )
293
280
{
294
281
if ( supportsInitialization != null )
295
282
{
296
283
supportsInitialization . EndInit ( ) ;
297
284
}
298
- return document ;
299
- }
300
- else
301
- {
302
- return CreateInstanceUsingCreator ( values ) ;
285
+ return ( TClass ) document ;
303
286
}
287
+
288
+ return CreateInstanceUsingCreator ( values ) ;
304
289
}
305
290
306
291
/// <summary>
@@ -372,20 +357,18 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati
372
357
if ( value == null )
373
358
{
374
359
bsonWriter . WriteNull ( ) ;
360
+ return ;
375
361
}
376
- else
362
+
363
+ var actualType = value . GetType ( ) ;
364
+ if ( actualType == typeof ( TClass ) )
377
365
{
378
- var actualType = value . GetType ( ) ;
379
- if ( actualType == typeof ( TClass ) )
380
- {
381
- SerializeClass ( context , args , value ) ;
382
- }
383
- else
384
- {
385
- var serializer = BsonSerializer . LookupSerializer ( actualType ) ;
386
- serializer . Serialize ( context , args , value ) ;
387
- }
366
+ SerializeClass ( context , args , value ) ;
367
+ return ;
388
368
}
369
+
370
+ var serializer = BsonSerializer . LookupSerializer ( actualType ) ;
371
+ serializer . Serialize ( context , args , value ) ;
389
372
}
390
373
391
374
/// <summary>
@@ -433,14 +416,7 @@ private BsonCreatorMap ChooseBestCreator(Dictionary<string, object> values)
433
416
private TClass CreateInstanceUsingCreator ( Dictionary < string , object > values )
434
417
{
435
418
var creatorMap = ChooseBestCreator ( values ) ;
436
- var document = creatorMap . CreateInstance ( values ) ; // removes values consumed
437
-
438
- if ( values . Count > 0 && _isValueType )
439
- {
440
- var message = string . Format ( "Value class {0} cannot be deserialized unless all values can be passed to a constructor." , _classMap . ClassType . FullName ) ;
441
- throw new BsonSerializationException ( message ) ;
442
- }
443
-
419
+ object document = creatorMap . CreateInstance ( values ) ; // removes values consumed
444
420
var supportsInitialization = document as ISupportInitialize ;
445
421
if ( supportsInitialization != null )
446
422
{
@@ -473,8 +449,6 @@ private void DeserializeExtraElementMember(
473
449
string elementName ,
474
450
BsonMemberMap extraElementsMemberMap )
475
451
{
476
- var bsonReader = context . Reader ;
477
-
478
452
if ( extraElementsMemberMap . MemberType == typeof ( BsonDocument ) )
479
453
{
480
454
var extraElements = ( BsonDocument ) extraElementsMemberMap . Getter ( obj ) ;
@@ -514,8 +488,6 @@ private void DeserializeExtraElementValue(
514
488
string elementName ,
515
489
BsonMemberMap extraElementsMemberMap )
516
490
{
517
- var bsonReader = context . Reader ;
518
-
519
491
if ( extraElementsMemberMap . MemberType == typeof ( BsonDocument ) )
520
492
{
521
493
BsonDocument extraElements ;
@@ -561,8 +533,6 @@ private void DeserializeExtraElementValue(
561
533
562
534
private object DeserializeMemberValue ( BsonDeserializationContext context , BsonMemberMap memberMap )
563
535
{
564
- var bsonReader = context . Reader ;
565
-
566
536
try
567
537
{
568
538
return memberMap . GetSerializer ( ) . Deserialize ( context ) ;
0 commit comments