Cancel sorting by user list

I created my own List class, which supports a set of item identifiers for the following reasons:

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

I want to deserialize this list from a simple JSON array, for example:

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

this will cause JSON.NET to call only the empty constructor, so the itemID list will remain empty. Also, the Add method is not called.

How JSON.NET adds items to the list, so I can add logic to this place.

(we are talking about deserialization without properties that should be constant in the json string, so the proposed duplicate question has nothing to do with this)

+5
source share
3 answers

Your problem is not JSON deserialization; your MyCustomList class must be retrieved from IList if you want to override the Add method. See IT for more details.

0
source

Decision:

 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(); } } 
+3
source

You can deserialize the form that the constructor expects, and then name it yourself.

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

Source: https://habr.com/ru/post/1235112/


All Articles