反序列化会导致List-Entries的副本

时间:2016-03-30 16:25:47

标签: c# json serialization

我想创建一个非常通用的Model-Layer,它也可以作为JSON传递。一个型号应该显示一个RaspberryPi2的LED面板。因为我想将Class建模为尽可能接近现实,所以我强制List总是有8 * 8 Leds。班级看起来像这样:

A(arg, key=0)

序列化出现了问题:我正在使用NewtonSoft。 Json.Net Serializer,据我所见,它首先访问Getter,这会导致Logic创建Leds,然后设置它们。 我能想到的唯一解决方案可能是Custom-Deserializer或某种Constructor shennenigans。 看起来Deserializer似乎没有使用VisualLeds-Value的Set-Property,因为我的Debugger-Stop从未被命中过。

是否有一个简单的可能性来充分利用这两个世界?我希望模型尽可能通用而不需要Custom-Deserializer。

1 个答案:

答案 0 :(得分:2)

无需编写自己的custom JsonConverter即可完成此操作的最简单方法是将您的VisualLed个对象序列序列化为代理数组属性,标记为原始属性为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;
    }
}

原型fiddle

有关进一步的讨论,请参阅Why are all the collections in my POCO are null when deserializing some valid json with the .NET Newtonsoft.Json component。在这种情况下使用ObjectCreationHandling.Replace是不合适的,因为您希望Lazy<List<VisualLed>> _lazyVisualLeds是只读的。