反序列化会导致列表项的副本



我想创建一个非常通用的模型层,它也可以作为JSON传递。一个型号应显示RaspberryPi2的LED面板。由于我想将类建模为尽可能接近现实,因此我强制List始终具有8*8个Led。课堂看起来是这样的:

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,这会导致逻辑创建Led,然后设置它们。我能想到的唯一解决方案要么是自定义反序列化器,要么是某种构造函数shennenigans。反序列化程序似乎也没有使用VisualLeds值的Set属性,因为我的Debugger Stop从未被击中。

有没有一种简单的可能性可以两全其美?我希望模型尽可能通用,而不需要自定义反序列化程序。

要做到这一点,而不必编写自己的自定义JsonConverter,最简单的方法是将VisualLed对象集合序列化为代理数组属性,将原始属性标记为忽略:

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;
    }
}

原型小提琴

有关进一步的讨论,请参阅在使用.NET Newtonsoft.json组件反序列化某些有效json时,为什么我的POCO中的所有集合都为null。在这种情况下,使用ObjectCreationHandling.Replace是不合适的,因为您希望Lazy<List<VisualLed>> _lazyVisualLeds是只读的。

最新更新