大家好,我试图解决以下问题。 我想反序列化Foo类,该类包含Bar对象的列表,而这些对象又包含对Foo对象的引用。 Bar对象中的Foo对象用于检索Num1,从而依次执行一些内部计算(以获取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;
}
}
如果我像下面的示例那样对其进行序列化,则可以正常运行:
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}]}
但是,如果我尝试反序列化同一字符串:
Foo deserialised = (Foo)JsonConvert.DeserializeObject(serialised, typeof(Foo));
Foo对象被反序列化,但是Num3属性引发以下空引用错误:
(新的System.Collections.Generic.ICollectionDebugView(deserialized.Bars).Items [1])。Num3'引发了类型为'System.NullReferenceException'的异常
这只是一个简单的示例,用于显示我遇到的问题,我认为原因是因为json中的Bar对象没有引用任何Foo对象。实际上,“ Num1”是一个复杂的对象,可以从中检索其他参数,因此无法将Num1存储在Bar类中。
是否有解决此类问题的聪明方法?
编辑:
因此,我发现的临时解决方案是修改上面的代码1),按照Matt Dillard(以及相关的私有字段_Num3)的建议添加设置器,并通过创建用于定义Num3的函数(CalculateNum3)来修改上述代码。在主例程中调用,并更新_Num3的值。这样,Num3由一个函数设置,并且无论何时进行反序列化或序列化,它们都会作用于Num3字段。主要缺点是需要每次调用CalculateNum3函数。
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;
}
}
主要代码
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);
答案 0 :(得分:0)
您的问题是Bar.Num3
属性尚未设置。从字符串反序列化时,JSON.NET将创建Bar
类的全新实例,并将JSON字符串中的值分配给对象。它尝试调用Num3
属性的设置器,但没有。