Hi guys just trying to get my head around the following issue. I want to deserialise the Foo class, which contains a list of Bar objects that in turn contain a reference to the Foo object. The Foo object in the Bar object is used to retrieve Num1 to perform, in turn, some internal calculations (to get Num3):
public class Foo
{
[JsonProperty]
public double Num1 { get; set; }
[JsonProperty]
public List<Bar> Bars { get; set; }
}
public class Bar
{
[JsonProperty]
public double Num2 { get; set; }
[JsonProperty]
public double Num3 => Foo.Num1 * 2;
private Foo Foo;
public Bar(Foo foo, double num2)
{
Foo = foo;
Num2 = num2;
}
}
If I serialise it like in the example below, it works ok:
Foo foo = new Foo()
{
Num1 = 8,
Bars = new List<Bar>()
};
foo.Bars.Add(new Bar(foo, 3));
foo.Bars.Add(new Bar(foo, 5));
string serialised = JsonConvert.SerializeObject(foo);
// result is {"Num1":8.0,"Bars":[{"Num2":3.0,"Num3":24.0},{"Num2":5.0,"Num3":40.0}]}
However, if I try to deserialise the same string:
Foo deserialised = (Foo)JsonConvert.DeserializeObject(serialised, typeof(Foo));
The Foo object gets deserialised, but the Num3 property raises the following null reference error:
(new System.Collections.Generic.ICollectionDebugView(deserialised.Bars).Items[1]).Num3' threw an exception of type 'System.NullReferenceException'
This is just a simple example to show the issue that I am having and I think that the reason is because the Bar object in the json has no reference to any Foo object. In reality, "Num1" is a complex object from which I am retrieving other parameters, so I cannot store Num1 in the Bar class.
Is there a clever way to tackle this type of issue?
EDIT:
So, the temporary solution I have found is to modify the above code 1) by adding the setter as suggested by Matt Dillard (and relevant private field _Num3) and 2) by creating a function (CalculateNum3) for the definition of Num3, which gets called in the main routine and updates the value of _Num3. In this way, Num3 is set by a function and whenever either deserialisation or serialisation occur, they act on the Num3 field. Main drawback is the need to call the CalculateNum3 function each time.
public class Bar
{
[JsonProperty]
public double Num2 { get; set; }
private double _Num3;
[JsonProperty]
public double Num3
{
get
{
return _Num3;
}
private set
{
_Num3 = value;
}
}
public double CalculateNum3()
{
_Num3 = Foo.Num1 * Num2;
return _Num3;
}
private Foo Foo;
public Bar(Foo foo, double num2)
{
Foo = foo;
Num2 = num2;
}
}
Main code
Foo foo = new Foo()
{
Num1 = 8,
Bars = new List<Bar>()
};
Bar bar1 = new Bar(foo, 3);
bar1.CalculateNum3();
Bar bar2 = new Bar(foo, 5);
bar2.CalculateNum3();
foo.Bars.Add(bar1);
foo.Bars.Add(bar2);