Reputation: 6826
Newtonsoft's json Deserializer, JsonConvert.DeserializeObject<T>(json);
was deserializing my object wrong because it would not instantiate one of the properties. I wrote up a dotnetfiddle which shows the same problem.
Classes:
public class Right
{
private Property _property;
public Property Property
{
get { return _property; }
set { _property = value ?? new Property(); }
}
}
public class Wrong
{
private Property _property;
public Property Property
{
get { return _property ?? new Property(); }
set { _property = value; }
}
}
public class Property
{
public string Text { get; set; }
}
Main Program:
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
//Instantiate
var right = new Right();
var wrong = new Wrong();
//Initialize property
right.Property = new Property() { Text = "Right!" };
wrong.Property = new Property() { Text = "Wrong?" };
//Serialize
var jsonRight = JsonConvert.SerializeObject(right);
var jsonWrong = JsonConvert.SerializeObject(wrong);
//Print json
Console.WriteLine(jsonRight);
Console.WriteLine(jsonWrong);
//Deserialize
var dRight = JsonConvert.DeserializeObject<Right>(jsonRight);
var dWrong = JsonConvert.DeserializeObject<Wrong>(jsonWrong);
//Print property
Console.WriteLine("'" + dRight.Property.Text + "'");
Console.WriteLine("'" + dWrong.Property.Text + "'");
}
}
Output:
// {"Property":{"Text":"Right!"}}
// {"Property":{"Text":"Wrong?"}}
// 'Right!'
// ''
Why can't the Deserializer do its thang when I'm doing return _property ?? new Property();
inside the getter method?
Upvotes: 3
Views: 1439
Reputation: 6430
Because -
public class Wrong
{
private Property _property;
public Property Property
{
get { return _property ?? new Property(); } // no assignment done to _property.
set { _property = value; }
}
}
This creates a new property whenever the property is null. But it does not update the _property
member, it is still the old one and still the null one. So, every time you use the property it creates a new object and returns it and forgets the reference when it runs out of scope. If does not matter whether you are using Json Converter
or anything. This is a very very very destructive appoach.
The right approach is this one -
public class Right
{
private Property _property;
public Property Property
{
get { return _property; }
set { _property = value ?? new Property(); } //initialized and assigned to _property
}
}
It initializes the property with new object if it is null and assigns to the member _property
. In future whenever you use this property, it has the proper reference and works properly.
BTW: This is not a problem. This is the required behavior.
Upvotes: 4