是否有一个列表<t>的C#通用容器,还有HashSet <t> </t> </t>

时间:2012-08-15 05:26:28

标签: c# set generic-list

我正在寻找一个C#通用容器,它是List<T>,但不允许重复元素。

换句话说,它是Set<T>,但也可以通过[index]运营商访问。

感谢。

3 个答案:

答案 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>(“任何”无关紧要,可以是Tint,等等) ,例如:

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。如果将类型用于键和值类型,并使用相同的对象作为键和值,则可以获得所需的行为(您还可以使用键集合进行基于索引的检索;并将虚拟数据粘贴到值中,但我不确定你会得到什么。