I have a number of records that look like this:
[<DataContract>]
type Rec1 = {
[<DataMember>] mutable field1 : int;
[<DataMember>] mutable field2 : string;
}
[<DataContact>]
type Rec2 = {
[<DataMember>] mutable field3 : Rec1;
[<DataMember>] mutable field4 : int;
}
I use DataContactJsonSerializer
to deserialize JSON into this structure. This is a valid JSON value:
{ "field3": null, "field4": 1 }
Which means at runtime, field3
is null/Unchecked.defaultOf<_>
. In Visual Studio 2010, this test works fine:
(deserialize<Rec2> "{ field3: null, field4: 1 }") = { field3 = Unchecked.defaultOf<_>; field4 = 1 } //true
In Visual Studio 2013, the same code throws a NullReferenceException
:
at Rec2.Equals(Rec2 obj)
Peeking at the code in ILSpy, I see this is generated:
if(this != null)
{
return obj != null && this.field3.Equals(obj.field3) && this.field4.Equals(obj.field4);
}
return obj == null;
So the issue is the compiler assumes that field3
is never null which isn't the case since DataContractJsonSerializer
sets the value to null
. I've tried applying the AllowNullLiteral
attribute to Rec1
but F# records aren't allowed to have that attribute applied to them. How can I either tell the compiler that the fields can be null
or re-structure my types to allow this to work?