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 AllowNullLiteralattribute 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?