我正在寻找一个集合,其中没有元素可以存在多次,并且也被索引。与Dictionary
类似,但没有Key,只有Value。与HashSet
类似,但已建立索引,因此我可以轻松检索元素而无需迭代集合。我希望这是有道理的。 :)
答案 0 :(得分:2)
答案 1 :(得分:1)
您可以使用Dictionary<T, T>
并使用Add(value, value)
插入元素。
但是,只有在您的类型正确实现Equals(object)
和GetHashCode()
时才有意义。如果它没有,则两个不同的实例将永远不会相等,而HashSet<T>
&#39; Contains(T)
方法已经告诉您是否具有nor的元素引用。
答案 2 :(得分:0)
HashSet类最适合您的工作。我不会允许重复输入。 请注意,如果项目已添加到集合中,HashSet.Add(T item)方法将返回 bool - true ;如果项目已经存在,则 false 。
只需添加一个Extension方法即可将异常抛出为
public static void AddOrThrow<T>(this HashSet<T> hash, T item)
{
if (!hash.Add(item))
throw new ValueExistingException();
}
答案 3 :(得分:0)
最简单的方法是创建一个实现IList<T>
但在内部使用List<T>
和HashSet<T>
的类。然后,您可以根据需要对每个集合执行每个方法。
using System;
using System.Collections.Generic;
namespace Example
{
public class UniqueList<T> : IList<T>
{
private readonly List<T> _list;
private readonly HashSet<T> _hashset;
public UniqueList()
{
_list = new List<T>();
_hashset = new HashSet<T>();
}
public UniqueList(IEqualityComparer<T> comparer)
{
_list = new List<T>();
_hashset = new HashSet<T>(comparer);
}
void ICollection<T>.Add(T item)
{
Add(item);
}
public bool Add(T item)
{
var added = _hashset.Add(item);
if (added)
{
_list.Add(item);
}
return added;
}
public void RemoveAt(int index)
{
_hashset.Remove(_list[index]);
_list.RemoveAt(index);
}
public T this[int index]
{
get { return _list[index]; }
set
{
var oldItem = _list[index];
_hashset.Remove(oldItem);
var added = _hashset.Add(value);
if (added)
{
_list[index] = value;
}
else
{
//Put the old item back before we raise a exception.
_hashset.Add(oldItem);
throw new InvalidOperationException("Object already exists.");
}
}
}
public int IndexOf(T item)
{
return _list.IndexOf(item);
}
void IList<T>.Insert(int index, T item)
{
Insert(index, item);
}
public bool Insert(int index, T item)
{
var added = _hashset.Add(item);
if (added)
{
_list.Insert(index, item);
}
return added;
}
public void Clear()
{
_list.Clear();
_hashset.Clear();
}
public bool Contains(T item)
{
return _hashset.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
var removed = _hashset.Remove(item);
if (removed)
{
_list.Remove(item);
}
return removed;
}
public int Count
{
get { return _list.Count; }
}
public IEnumerator<T> GetEnumerator()
{
return _list.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
我做了Add
和Insert
的显式实现,所以我可以给它们返回bool
的版本来判断操作是否成功。我无法在T this[int index]
setter中返回值,因此如果您尝试插入副本,我会抛出InvalidOperationException
。
如果您对副本执行ICollection.Add
,它就不会抛出,它只是不添加它。这是因为这是行为HashSet<T>.ICollection<T>.Add
,我想模仿它。