C#唯一索引泛型集合

时间:2011-07-10 14:07:47

标签: c# generics collections

我需要一个公开[]运算符的集合,它只包含唯一的对象,并且是通用的。有人可以帮忙吗?

5 个答案:

答案 0 :(得分:2)

Dictionary(Of TKey, TValue) Class表示键和值的集合。

答案 1 :(得分:1)

答案 2 :(得分:0)

HashSet类应该可以解决问题。有关详细信息,请参阅HashSet(Of T)。如果您需要它们来维护排序顺序,SortedSet应该可以解决问题。有关该课程的详细信息,请参阅SortedSet(Of T)

答案 3 :(得分:0)

这取决于你所说的“暴露[]运算符。”

如果您希望能够通过某个任意键访问唯一集合中的对象,请使用Dictionary<string key, object value>

如果您希望能够创建允许按顺序索引访问的唯一对象列表,则按照添加对象的顺序,您需要自己滚动一些东西。我不知道任何框架类既提供HashSet<T>这样的唯一性,也允许按照添加顺序访问对象,如List<T>SortedSet<T>几乎可以做到,但没有索引器访问权限 - 所以虽然它确实维护了顺序,但它不允许使用该命令进行访问,除非通过枚举。您可以使用Linq扩展方法ElementAt来访问特定序数索引处的元素,但性能会非常糟糕,因为此方法通过迭代工作。

你也可以使用Dictionary<int key, object value>,但你仍然需要自己维护索引,如果有任何东西被删除,你的列表中就会有一个漏洞。如果您不必删除元素,这将是一个很好的解决方案。

要通过索引同时具有唯一性和访问权限,并且还能够删除元素,您需要哈希表和有序列表的组合。我最近创建了这样一堂课。我认为这不一定是最有效的实现,因为它通过保留两个列表副本(一个作为List<T>,一个作为HashSet<T>)来完成其工作。

在我的情况下,我重视速度超过存储效率,因为数据量不大。此类为索引访问提供List<T>的速度,并为元素访问提供HashTable<T>的速度(例如,在添加时确保唯一性),但需要两倍的存储要求。

另一种方法是仅使用List<T>作为基础,并在任何添加/插入操作之前验证唯一性。这样可以提高内存效率,但添加/插入操作要慢得多,因为它没有利用哈希表。

这是我使用的课程。

http://snipt.org/xlRl

答案 4 :(得分:0)

如果您希望在展示[]时存储唯一对象(例如实体),则需要使用KeyedCollection类。

MSDN KeyedCollection

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

// This class represents a very simple keyed list of OrderItems,
// inheriting most of its behavior from the KeyedCollection and 
// Collection classes. The immediate base class is the constructed
// type KeyedCollection<int, OrderItem>. When you inherit
// from KeyedCollection, the second generic type argument is the 
// type that you want to store in the collection -- in this case
// OrderItem. The first type argument is the type that you want
// to use as a key. Its values must be calculated from OrderItem; 
// in this case it is the int field PartNumber, so SimpleOrder
// inherits KeyedCollection<int, OrderItem>.
//
public class SimpleOrder : KeyedCollection<int, OrderItem>
{
    // The parameterless constructor of the base class creates a 
    // KeyedCollection with an internal dictionary. For this code 
    // example, no other constructors are exposed.
    //
    public SimpleOrder() : base() {}

    // This is the only method that absolutely must be overridden,
    // because without it the KeyedCollection cannot extract the
    // keys from the items. The input parameter type is the 
    // second generic type argument, in this case OrderItem, and 
    // the return value type is the first generic type argument,
    // in this case int.
    //
    protected override int GetKeyForItem(OrderItem item)
    {
        // In this example, the key is the part number.
        return item.PartNumber;
    }
}