Search code examples
c#classgenericsgeneric-list

Defining custom collection class based on list. How to access elements that are stored in the instance?


Creating custom data collection class that inherits methods from List. This new type holds items in a queue, has private dictionary that holds all the items and corresponding IDs that when new item is add checks if there already is item with same ID in the queue and replaces it. Wondering is there way to access that element (which has same ID) and overwrite it.

I already implemented a way that when there are two items with same ID, code finds index of the item in queue, deletes it, inserts new item and updates the dictionary. It works perfectly, but I am wondering if there is a way make this action more efficient and thought that overwriting is easier than deleting and inserting.

public void Enqueue(T item, string uniqueID)
    {
        if (entries.ContainsKey(uniqueID))
        {
            int index = base.IndexOf(entries[uniqueID]);
            base.Remove(entries[uniqueID]);
            base.Insert(index, item);
            entries[uniqueID] = item;
        }
        else
        {
            base.Add(item);
            entries.Add(uniqueID, item);
        }
    }

entries is the dictionary that holds string and T

This entire class definition

using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
/// <summary>
/// Queue based on class that has only one entry with unique ID
/// </summary>
/// /// /// <remarks>
/// When adding value with same ID old value is overwriten but place in the queue is maintained
/// </remarks>
/// <typeparam name="T"></typeparam>

public class ListQueueSet<T>:List<T>
{
    new public void Add(T item) { throw new NotSupportedException(); }
    new public void AddRange(IEnumerable<T> collection) { throw new NotSupportedException(); }
    new public void Insert(int index, T item) { throw new NotSupportedException(); }
    new public void InsertRange(int index, IEnumerable<T> collection) { throw new NotSupportedException(); }
    new public void Reverse() { throw new NotSupportedException(); }
    new public void Reverse(int index, int count) { throw new NotSupportedException(); }
    new public void Sort() { throw new NotSupportedException(); }
    new public void Sort(Comparison<T> comparison) { throw new NotSupportedException(); }
    new public void Sort(IComparer<T> comparer) { throw new NotSupportedException(); }
    new public void Sort(int index, int count, IComparer<T> comparer) { throw new NotSupportedException(); }
    new public void Remove(T item) { throw new NotSupportedException(); }

    private Dictionary<string, T> entries;

    public ListQueueSet()
    {
        entries = new Dictionary<string, T>();
    }

    public void Enqueue(T item, string uniqueID)
    {
        if (entries.ContainsKey(uniqueID))
        {
            int index = base.IndexOf(entries[uniqueID]);
            base.Remove(entries[uniqueID]);
            base.Insert(index, item);
            entries[uniqueID] = item;
        }
        else
        {
            base.Add(item);
            entries.Add(uniqueID, item);
        }
    }

    public T Dequeue()
    {
        var t = base[0];
        base.RemoveAt(0);

        entries.Remove(entries.FirstOrDefault(x => x.Value.Equals(t)).Key);
        return t;
    }

    public T Peek()
    {
        return base[0];
    }
}

Solution

  • int index = base.IndexOf(entries[uniqueID]);
    this[index] = item;
    entries[uniqueID] = item;
    

    apparently, this[index] allows you to access inside of the list you declare