c#唯一索引泛型集合

本文关键字:集合 泛型 索引 唯一 | 更新日期: 2023-09-27 18:01:36

我需要一个集合,它公开[]操作符,只包含唯一的对象,并且是泛型的。有人能帮忙吗?

c#唯一索引泛型集合

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

HashSet<T>

这取决于您所说的"暴露[]操作符"的含义。

如果您希望能够通过任意键访问唯一集合中的对象,则使用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

HashSet类应该可以做到这一点。参见HashSet(Of T)了解更多信息。如果您需要它们来维护一个有序的顺序,SortedSet应该可以做到这一点。有关该类的更多信息,请参见SortedSet(Of T)。

如果您希望在公开[]时存储唯一对象(例如实体),那么您需要使用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;
    }
}