反序列化导致List-Entries的副本 [英] Deserialization causes copies of List-Entries
问题描述
我想创建一个非常通用的Model-Layer,也可以将其作为JSON传递.一个模型应显示RaspberryPi2的LED面板.由于我想对Class建模,使其尽可能接近实际情况,因此我强制List始终具有8 * 8 Led.该类看起来像这样:
I'd like to create a very general Model-Layer, which can also be passed arround as JSON. One Model should show a LED-Panel of a RaspberryPi2. Since I'd like to model the Class to be as near as possible to the reality, I force a List to always have 8 * 8 Leds. The Class is looking like this:
public class VisualLedPanel
{
private readonly Lazy<List<VisualLed>> _lazyVisualLeds = new Lazy<List<VisualLed>>(CreateVisualLeds);
public VisualLed this[int x, int y]
{
get
{
var result = VisualLeds.FirstOrDefault(f => f.X == x && f.Y == y);
return result;
}
}
public IEnumerable<VisualLed> VisualLeds
{
get
{
return _lazyVisualLeds.Value;
}
set
{
var tt = value;
}
}
private static List<VisualLed> CreateVisualLeds()
{
var result = new List<VisualLed>();
for (var x = 0; x <= 7; x++)
{
for (var y = 0; y <= 7; y++)
{
result.Add(new VisualLed(x, y));
}
}
return result;
}
}
序列化出现问题:我正在使用NewtonSoft. Json.Net Serializer,据我所知,它首先访问Getter,这将导致Logic创建Led,然后对其进行设置. 我唯一想到的解决方案要么是Custom-Deserializer,要么是某些Constructor shennenigans. 似乎反序列化程序没有使用VisualLeds值的Set-Property,因为我的Debugger-Stop从未被击中.
The problem arises with the Serialization: I'm using the NewtonSoft. Json.Net Serializer, and as far as I've seen, it first accesses the Getter, which causes the Logic to create the Leds, and then sets them afterwards. The only solution I could think of would either be a Custom-Deserializer or some sort of Constructor shennenigans. It also seems like the Deserializer doesn't use the Set-Property of the VisualLeds-Value, since my Debugger-Stop never was hitted.
同时拥有两全其美的方法是否容易?我想在不需要Custom-Deserializer的情况下使模型尽可能通用.
Is there an easy possibility arround to have the best of both worlds? I'd like to have the Model as general as possible without the need of Custom-Deserializer.
推荐答案
无需编写自己的忽略:
The easiest way for you to do this without having to write your own custom JsonConverter
will be to serialize your collection of VisualLed
objects as a proxy array property, marking the original property as ignored:
public class VisualLedPanel
{
private readonly Lazy<List<VisualLed>> _lazyVisualLeds = new Lazy<List<VisualLed>>(CreateVisualLeds);
public VisualLed this[int x, int y]
{
get
{
var result = VisualLeds.FirstOrDefault(f => f.X == x && f.Y == y);
return result;
}
}
[JsonIgnore]
public IEnumerable<VisualLed> VisualLeds
{
get
{
return _lazyVisualLeds.Value;
}
}
[JsonProperty("VisualLeds")]
VisualLed [] SerializableVisualLeds
{
get
{
return VisualLeds.ToArray();
}
set
{
if (value == null || value.Length == 0)
{
if (_lazyVisualLeds.IsValueCreated)
_lazyVisualLeds.Value.Clear();
}
else
{
_lazyVisualLeds.Value.Clear();
_lazyVisualLeds.Value.AddRange(value);
}
}
}
private static List<VisualLed> CreateVisualLeds()
{
var result = new List<VisualLed>();
for (var x = 0; x <= 7; x++)
{
for (var y = 0; y <= 7; y++)
{
result.Add(new VisualLed(x, y));
}
}
return result;
}
}
原型小提琴
有关进一步的讨论,请参见 ObjectCreationHandling.Replace
是不合适的,因为您需要Lazy<List<VisualLed>> _lazyVisualLeds
为只读.
For a further discussion, see Why are all the collections in my POCO are null when deserializing some valid json with the .NET Newtonsoft.Json component. Using ObjectCreationHandling.Replace
would not be appropriate in this case since you want your Lazy<List<VisualLed>> _lazyVisualLeds
to be read-only.
这篇关于反序列化导致List-Entries的副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!