反序列化为自定义列表

本文关键字:列表 自定义 反序列化 | 更新日期: 2023-09-27 18:20:25

我创建了一个自定义List类,该类出于性能原因维护了一组项目ID:

public class MyCustomList : List<ItemWithID>
{
    private HashSet<int> itemIDs = new HashSet<int>();
    public MyCustomList()
    {
    }
    [JsonConstructor]
    public MyCustomList(IEnumerable<ItemWithID> collection)
        : base(collection)
    {
        itemIDs = new HashSet<int>(this.Select(i => i.ID));
    }
    public new void Add(ItemWithID item)
    {
        base.Add(item);
        itemIDs.Add(item.ID);
    }
    public new bool Remove(ItemWithID   item)
    {
        var removed = base.Remove(item);
        if (removed)
        {
            itemIDs.Remove(item.ID);
        }
        return removed;
    }
    public bool ContainsID(int id)
    {
        return itemIDs.Contains(id);
    }
}

我想从一个简单的JSON数组中反序列化这个列表,例如:

JsonConvert.DeserializeObject<MyCustomList>("[{ID:8},{ID:9}]");

这将导致JSON.NET只调用空的构造函数,因此我的itemID列表保持为空。此外,Add方法也不会被调用。

JSON.NET如何将项目添加到列表中,以便在该位置添加逻辑。

(这是关于没有应该在json字符串中持久化的属性的反序列化,所以建议的重复问题与此无关)

反序列化为自定义列表

解决方案:

public class MyCustomList : IList<ItemWithID>
{
    private HashSet<int> itemIDs = new HashSet<int>();
    private List<ItemWithID> actualList = new List<ItemWithID>();
    public void Add(ItemWithID item)
    {
        actualList.Add(item);
        itemIDs.Add(item.ID);
    }
    public bool Remove(ItemWithID item)
    {
        var removed = actualList.Remove(item);
        if (removed)
        {
            itemIDs.Remove(item.ID);
        }
        return removed;
    }
    public bool ContainsID(int id)
    {
        return itemIDs.Contains(id);
    }
    public int IndexOf(ItemWithID item)
    {
        return actualList.IndexOf(item);
    }
    public void Insert(int index, ItemWithID item)
    {
        actualList.Insert(index, item);
        itemIDs.Add(item.ID);
    }
    public void RemoveAt(int index)
    {
        itemIDs.Remove(actualList[index].ID);
        actualList.RemoveAt(index);
    }
    public ItemWithID this[int index]
    {
        get
        {
            return actualList[index];
        }
        set
        {
            actualList[index] = value;
            if (!itemIDs.Contains(value.ID))
            {
                itemIDs.Add(value.ID);
            }
        }
    }
    public void Clear()
    {
        actualList.Clear();
        itemIDs.Clear();
    }
    public bool Contains(ItemWithID item)
    {
        return actualList.Contains(item);
    }
    public void CopyTo(ItemWithID[] array, int arrayIndex)
    {
        actualList.CopyTo(array, arrayIndex);
    }
    public int Count
    {
        get { return actualList.Count; }
    }
    public bool IsReadOnly
    {
        get { return false; }
    }
    public IEnumerator<ItemWithID> GetEnumerator()
    {
        return actualList.GetEnumerator();
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

您可以反序列化为构造函数所需的形式,然后自己调用它。

var collection = JsonConvert.DeserializeObject<ItemID[]>("[{ID:8},{ID:9}]");
var aCustomList = new MyCustomList(collection);

您的问题不是JSON反序列化,如果您想覆盖Add方法,MyCustomList类需要从IList派生。有关详细信息,请参阅此。