C# 是否存在这样的集合(字典和哈希集的功能)?

C# 是否存在这样的集合(字典和哈希集的功能)?,c#,list,dictionary,collections,hashset,C#,List,Dictionary,Collections,Hashset,我正在寻找一个集合,其中没有任何元素可以存在一次以上,并且也被索引。类似于字典,但没有键,只有值。类似于HashSet,但已编制索引,因此我可以轻松检索元素,而无需迭代集合。我希望这是有道理的 您可以使用哈希集。它是“索引”的,毕竟,如果没有索引,性能将是缺乏的 使用该方法“检索”元素。如果您也要删除它,请使用 这两种方法都是O(1)运算。您可以使用字典,并使用Add(value,value)插入元素 但是,只有当您的类型正确地实现了Equals(object)和GetHashCode()时,这

我正在寻找一个集合,其中没有任何元素可以存在一次以上,并且也被索引。类似于
字典
,但没有键,只有值。类似于
HashSet
,但已编制索引,因此我可以轻松检索元素,而无需迭代集合。我希望这是有道理的

您可以使用
哈希集
。它是“索引”的,毕竟,如果没有索引,性能将是缺乏的

使用该方法“检索”元素。如果您也要删除它,请使用


这两种方法都是O(1)运算。

您可以使用
字典
,并使用
Add(value,value)
插入元素


但是,只有当您的类型正确地实现了
Equals(object)
GetHashCode()
时,这才有意义。否则,两个不同的实例将永远不相等,
HashSet
包含(t)
方法已经告诉您是否具有nor的元素引用。

HashSet类最适合您的工作。我不允许重复输入。 请注意,如果项目被添加到集合中,HashSet.Add(T item)方法将返回一个bool--truefalse如果项目已存在

只需添加一个扩展方法即可作为异常抛出

 public static void AddOrThrow<T>(this HashSet<T> hash, T item)
    {
        if (!hash.Add(item))
            throw new ValueExistingException();
    }
publicstaticvoidaddorthrow(此哈希集散列,T项)
{
如果(!hash.Add(项))
抛出新值existingexception();
}

最简单的方法是创建一个实现
IList
但在内部使用
列表和
哈希集的类。然后,您只需让每个方法根据需要对每个集合进行操作

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

    }
}
使用系统;
使用System.Collections.Generic;
名称空间示例
{
公共类唯一列表:IList
{
私有只读列表_List;
私有只读哈希集\u哈希集;
公共唯一列表()
{
_列表=新列表();
_hashset=新的hashset();
}
公共唯一列表(IEqualityComparer比较器)
{
_列表=新列表();
_hashset=新的hashset(比较器);
}
作废ICollection.Add(T项)
{
增加(项目);
}
公共布尔添加(T项)
{
var added=\u hashset.Add(项);
如有(新增)
{
_列表。添加(项目);
}
增加了退货;
}
公共无效删除(整数索引)
{
_删除(_list[index]);
_列表。删除(索引);
}
公共T此[int索引]
{
获取{return _list[index];}
设置
{
var oldItem=_列表[索引];
_hashset.Remove(oldItem);
var added=\u hashset.Add(值);
如有(新增)
{
_列表[索引]=值;
}
其他的
{
//在引发异常之前,请将旧项目放回原处。
_hashset.Add(oldItem);
抛出新的InvalidOperationException(“对象已存在”);
}
}
}
公共整数索引(T项)
{
返回(项目)的列表索引;
}
void IList.Insert(整型索引,T项)
{
插入(索引,项目);
}
公共布尔插入(整数索引,T项)
{
var added=\u hashset.Add(项);
如有(新增)
{
_列表。插入(索引,项目);
}
增加了退货;
}
公共空间清除()
{
_list.Clear();
_Clear();
}
公共布尔包含(T项)
{
返回_hashset.Contains(项);
}
public void CopyTo(T[]数组,int arrayIndex)
{
_CopyTo(数组,arrayIndex);
}
公共图书馆是只读的
{
获取{return false;}
}
公共布尔删除(T项)
{
var removed=\u hashset.Remove(项);
如果(已删除)
{
_列表。删除(项目);
}
移除返回;
}
公共整数计数
{
获取{return\u list.Count;}
}
公共IEnumerator GetEnumerator()
{
返回_list.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
返回GetEnumerator();
}
}
}
我做了
Add
Insert
的显式实现,这样我可以给他们返回
bool
的版本来判断操作是否成功。我无法在
T此[int index]
setter中返回值,因此如果您尝试插入重复项,我会让它抛出
invalidoOperationException


如果您执行
ICollection.Add
对副本执行操作,它不会抛出。它只是不添加副本。这是因为这是HashSet.ICollection.Add的行为,我想模仿它。

取决于你对“索引”的定义,你能更详细地说明你将如何使用所述索引吗?如果你想检索hash集中的实际对象,如果给定另一个与之相等的对象,那么这没有帮助。