HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

An ordered set in C#

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
setorderedstackoverflow

Problem

I need a generic data structure that ensures that its elements are unique. C# has HashSet, great!

As it turns out, the elements have to stay in the order in which they were added, too. This sounds more like List.

I tried to create my own:

```
using System.Collections;
using System.Collections.Generic;

namespace Collections.Generic
{
public class HashSetList : IList
{
private List _list;
private HashSet _set;

public HashSetList()
{
_list = new List();
_set = new HashSet();
}

public int IndexOf(T item)
{
return _list.IndexOf(item);
}

public void Insert(int index, T item)
{
if (_set.Add(item))
{
_list.Insert(index, item);
}
}

public void RemoveAt(int index)
{
_set.Remove(_list[index]);

_list.RemoveAt(index);
}

public T this[int index]
{
get
{
return _list[index];
}
set
{
if (_set.Add(value))
{
_list[index] = value;
};
}
}

public void Add(T item)
{
if (_set.Add(item))
{
_list.Add(item);
}
}

public void Clear()
{
_list.Clear();
_set.Clear();
}

public bool Contains(T item)
{
return _set.Contains(item);
}

public void CopyTo(T[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}

public int Count
{
get
{
return _list.Count;
}
}

public bool IsReadOnly
{
get
{
return false;
}
}

public bool

Solution

From the technical point of view you could implement both interfaces at the same time but you'd have to implement the Add method explicitly and without repeating yourself it would go like this:

void ICollection.Add(T item)
{
    ((ISet)this).Add(item);
}

bool ISet.Add(T item)
{
    if (_set.Add(item))
    {
        _list.Add(item);
        return true;
    }
    return false;
}


Which leads to one issue in your code namely the indexer repeats the insertion. You should use the insert method here:

public T this[int index]
{
    get
    {
        return _list[index];
    }
    set
    {
        Insert(index, value);
    }
}

Code Snippets

void ICollection<T>.Add(T item)
{
    ((ISet<T>)this).Add(item);
}

bool ISet<T>.Add(T item)
{
    if (_set.Add(item))
    {
        _list.Add(item);
        return true;
    }
    return false;
}
public T this[int index]
{
    get
    {
        return _list[index];
    }
    set
    {
        Insert(index, value);
    }
}

Context

StackExchange Code Review Q#132096, answer score: 6

Revisions (0)

No revisions yet.