C# 反序列化到自定义列表

C# 反序列化到自定义列表,c#,json,inheritance,json.net,C#,Json,Inheritance,Json.net,出于性能原因,我创建了一个自定义列表类,该类维护一组项目ID: public class MyCustomList : List<ItemWithID> { private HashSet<int> itemIDs = new HashSet<int>(); public MyCustomList() { } [JsonConstructor] public MyCustomList(IEnumerable&

出于性能原因,我创建了一个自定义列表类,该类维护一组项目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);
    }
}
公共类MyCustomList:List
{
私有HashSet itemIDs=新HashSet();
公共MyCustomList()
{
}
[JsonConstructor]
公共MyCustomList(IEnumerable集合)
:基本(集合)
{
itemIDs=newhashset(this.Select(i=>i.ID));
}
公共新作废添加(ItemWithID项)
{
基础。添加(项目);
添加(item.ID);
}
public new bool Remove(ItemWithID项)
{
var移除=基本移除(项目);
如果(已删除)
{
删除(item.ID);
}
移除返回;
}
公共bool ContainsID(int-id)
{
返回itemIDs.Contains(id);
}
}
我想从简单的JSON数组反序列化此列表,例如:

JsonConvert.DeserializeObject<MyCustomList>("[{ID:8},{ID:9}]");
JsonConvert.DeserializeObject(“[{ID:8},{ID:9}]”);
这将导致JSON.NET只调用空构造函数,因此我的itemIDs列表保持为空。此外,不会调用Add方法

JSON.NET如何将这些项添加到列表中,以便我可以在该位置添加逻辑


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

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

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

var aCustomList = new MyCustomList(collection);
var collection=JsonConvert.DeserializeObject(“[{ID:8},{ID:9}]”);
var aCustomList=新的MyCustomList(集合);
解决方案:

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();
    }
}
公共类MyCustomList:IList
{
私有HashSet itemIDs=新HashSet();
私有列表actualList=新列表();
公共作废添加(ItemWithID项)
{
实际值。添加(项目);
添加(item.ID);
}
公共bool删除(ItemWithID项)
{
var移除=实际值移除(项目);
如果(已删除)
{
删除(item.ID);
}
移除返回;
}
公共bool ContainsID(int-id)
{
返回itemIDs.Contains(id);
}
public int IndexOf(ItemWithID项)
{
返回(项目)的actualList.IndexOf;
}
公共void插入(int索引,ItemWithID项)
{
插入(索引,项目);
添加(item.ID);
}
公共无效删除(整数索引)
{
Remove(actualList[index].ID);
实际删除(索引);
}
具有此[int索引]ID的公共项
{
得到
{
返回实际值[索引];
}
设置
{
实际值[索引]=值;
如果(!itemIDs.Contains(value.ID))
{
Add(value.ID);
}
}
}
公共空间清除()
{
actualist.Clear();
itemIDs.Clear();
}
公共bool包含(ItemWithID项)
{
返回actualList.Contains(项目);
}
public void CopyTo(ItemWithID[]数组,int arrayIndex)
{
CopyTo(数组,数组索引);
}
公共整数计数
{
获取{return actualList.Count;}
}
公共图书馆是只读的
{
获取{return false;}
}
公共IEnumerator GetEnumerator()
{
返回actualList.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
}

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

不重复(请参阅更新的问题)您的问题不在于JSON反序列化,如果您希望能够覆盖
Add
方法,您的
MyCustomList
需要从
IList
派生。有关详细信息,请参阅。@Meehow谢谢,现在我了解了new和override之间的区别。回答这个问题,我会接受的。亲爱的@jan-s,你不喜欢我的答案,因为我的答案包含了实际的工作代码,因为你在45分钟后贴出了另一个答案?@OguzOzgul是的,你的答案是一个解决方案,但是我遗漏了一个解释。我可以问一下,除了分成两行之外,这与当前的实现有什么不同吗?唯一的缺点是MyCustomList被另一方反序列化(例如WebAPI)项目id列表将再次为空。@MeeJSONConvert反序列化到的类型不同。此外,然后使用该结果调用所需的构造函数。在原始代码中调用空构造函数。@OguzOzgul这正是问题所在。反序列化示例被简化,而不是实际用例