我正在寻找一个C#通用容器,它是List<T>
,但不允许重复元素。
换句话说,它是Set<T>
,但也可以通过[index]
运营商访问。
感谢。
答案 0 :(得分:1)
根据评论中的建议,您可以实施委派给内部IList<T>
实例的List<T>
,并使用HashSet<T>
保护添加和删除调用:
public class UniqueList<T> : IList<T>
{
private readonly List<T> list=new List<T>();
private readonly HashSet<T> set=new HashSet<T>();
public IEnumerator<T> GetEnumerator()
{
return list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T item)
{
if(set.Add(item))
{
list.Add(item);
}
}
public void Clear()
{
set.Clear();
list.Clear();
}
public bool Contains(T item)
{
return set.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
list.CopyTo(array,arrayIndex);
}
public bool Remove(T item)
{
if(set.Remove(item))
{
list.Remove(item);
return true;
}
return false;
}
public int Count { get { return list.Count; } }
public bool IsReadOnly { get { return false; } }
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)
{
T item = list[index];
set.Remove(item);
list.RemoveAt(index);
}
public T this[int index]
{
get { return list[index]; }
set {
T item = list[index];
set.Remove(item);
if(set.Add(value))
{
list[index] = value;
}
else
{
set.Add(item);
throw new Exception();
}
}
}
}
我没有编译这段代码,但你明白了......
答案 1 :(得分:1)
框架中没有提供此类内容(HashSet<T>
不保证任何特定订单,因此您不能使用ElementAt
作弊。您可以使用的最近的内置类似于SortedList<T,anything>
(“任何”无关紧要,可以是T
,int
,等等) ,例如:
var data = new SortedList<string, int>();
data["abc"] = 1;
data["def"] = 1;
data["abc"] = 1;
var thisIsTrue = data.ContainsKey("def");
var thisIsFalse = data.ContainsKey("ghi");
for (int i = 0; i < data.Count; i++) // 2 iterations
Console.WriteLine(data.Keys[i]); // abc, def
然而;请务必注意,此处的保证订单是密钥订单,而不是广告订单。密钥索引可通过data.IndexOfKey
获得。
答案 2 :(得分:0)
您可以使用OrderedDictionary。如果将类型用于键和值类型,并使用相同的对象作为键和值,则可以获得所需的行为(您还可以使用键集合进行基于索引的检索;并将虚拟数据粘贴到值中,但我不确定你会得到什么。