c#唯一索引泛型集合
本文关键字:集合 泛型 索引 唯一 | 更新日期: 2023-09-27 18:01:36
我需要一个集合,它公开[]操作符,只包含唯一的对象,并且是泛型的。有人能帮忙吗?
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/xlRlHashSet类应该可以做到这一点。参见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;
}
}