2015-11-03 150 views
5

我创建了一个自定义列表类维护一组项目的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字符串持久性,所以建议重复的问题无关,与此一)

+1

不是重复的(请参阅更新的问题) –

+1

您的问题不是JSON反序列化,如果您希望能够*重写*'Add'方法,'MyCustomList'需要从'IList'派生。有关详细信息,请参见[THIS](http://stackoverflow.com/q/580202/2140173)。 – 2015-11-03 11:41:54

+0

@Meehow现在感谢我了解新和覆盖之间的区别。让这个答案,我会接受它。 –

回答

0

你的问题不在于反序列化JSON,你MyCustomList类需要从IList推导,如果你希望能够覆盖Add方法。详情请参阅THIS

2

你可以反序列化的构造函数需要的形式,然后调用你自己。

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

var aCustomList = new MyCustomList(collection); 
+0

请问除了它被分成两行之外,这与现在的实现有什么不同吗? – 2015-11-03 11:36:33

+0

唯一的缺点是当MyCustomList被另一方反序列化时(例如WebAPI),项目ID列表将再次为空。 –

+1

@Meehow区别在于JsonConvert反序列化的类型。此外,然后使用该结果调用所需的构造函数。在原始代码中调用空构造函数。 – JonMac1374

3

解决方案:

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(); 
    } 
} 
相关问题