@@ -144,4 +144,48 @@ public void CanReadAllKindsOfDateTimes_DateTimeIsMemberOfTheRootRecord(DateTime
144
144
Assert . Equal ( input . Ticks , classRecord . GetDateTime ( nameof ( ClassWithDateTime . Value ) ) . Ticks ) ;
145
145
Assert . Equal ( input . Kind , classRecord . GetDateTime ( nameof ( ClassWithDateTime . Value ) ) . Kind ) ;
146
146
}
147
+
148
+ [ Fact ]
149
+ public void CanReadUserClassStoredAsSystemClass ( )
150
+ {
151
+ // For the following data, BinaryFormatter serializes the ClassWithNullableStructField class
152
+ // as a record with a single field called "NullableField" with BinaryType.SystemClass (!!!)
153
+ // and TypeName being System.Nullable`1[[SampleStruct, $AssemblyName]].
154
+ // It most likely does so, because it's System.Nullable<$NonSystemStruct>.
155
+ // But later it serializes the SampleStruct as a ClassWithMembersAndTypes record,
156
+ // not SystemClassWithMembersAndTypes.
157
+ // It does so, only when the payload contains at least one class with the nullable field being null.
158
+
159
+ using MemoryStream stream = Serialize (
160
+ new ClassWithNullableStructField [ ]
161
+ {
162
+ new ClassWithNullableStructField ( ) { NullableField = null } , // having a null here is crucial for the test
163
+ new ClassWithNullableStructField ( ) { NullableField = new ClassWithNullableStructField . SampleStruct ( ) { Value = 42 } }
164
+ }
165
+ ) ;
166
+
167
+ SZArrayRecord < SerializationRecord > arrayRecord = ( SZArrayRecord < SerializationRecord > ) NrbfDecoder . Decode ( stream ) ;
168
+ SerializationRecord [ ] records = arrayRecord . GetArray ( ) ;
169
+ Assert . Equal ( 2 , arrayRecord . Length ) ;
170
+ Assert . All ( records , record => Assert . True ( record . TypeNameMatches ( typeof ( ClassWithNullableStructField ) ) ) ) ;
171
+ Assert . Null ( ( ( ClassRecord ) records [ 0 ] ) . GetClassRecord ( nameof ( ClassWithNullableStructField . NullableField ) ) ) ;
172
+
173
+ ClassRecord ? notNullRecord = ( ( ClassRecord ) records [ 1 ] ) . GetClassRecord ( nameof ( ClassWithNullableStructField . NullableField ) ) ;
174
+ Assert . NotNull ( notNullRecord ) ;
175
+ Assert . Equal ( 42 , notNullRecord . GetInt32 ( nameof ( ClassWithNullableStructField . SampleStruct . Value ) ) ) ;
176
+ }
177
+
178
+ [ Serializable ]
179
+ public class ClassWithNullableStructField
180
+ {
181
+ #pragma warning disable IDE0001 // Simplify names
182
+ public System . Nullable < SampleStruct > NullableField ;
183
+ #pragma warning restore IDE0001
184
+
185
+ [ Serializable ]
186
+ public struct SampleStruct
187
+ {
188
+ public int Value ;
189
+ }
190
+ }
147
191
}
0 commit comments