C# unique index generic collection
I need a collection that exposes [] operator, contains only unique objects, and are gener开发者_开发问答ic. Anyone can help?
Dictionary(Of TKey, TValue) Class represents a collection of keys and values.
HashSet<T>
It depends what you mean by "exposes the [] operator."
If you want to be able to access objects in a unique collection by some arbitrary key, then use a Dictionary<string key, object value>
.
If you want to be able to create a list of unique objects which permits access by an ordinal index, in the order in which objects were added, you will need to roll something of your own. I am not aware of any framework class that offers both uniqueness like a HashSet<T>
and also allows access to objects in the order in which they were added, like a List<T>
. SortedSet<T>
almost does it, but does not have indexer access - so while it does maintain order, it does not allow access using that order except through enumeration. You could use Linq extension method ElementAt
to access the element at a particular ordinal index, but performance would be very bad since this method works by iteration.
You could use also Dictionary<int key, object value>
but you will still have to maintain the index yourself, and if anything is ever removed, you'd have a hole in your list. This would be a good solution if you never had to remove elements.
To have both uniqueness and access by index, and also be able to remove elements, you need a combination of a hash table and an ordered list. I created such a class recently. I don't think this is necessarily the most efficient implementation since it does its work by keeping two copies of the lists (one as a List<T>
and one as a HashSet<T>
).
In my situation, I valued speed over storage efficiency, since the amount of data wasn't large. This class offers the speed of a List<T>
for indexed access and the speed of a HashTable<T>
for element access (e.g. ensuring uniqueness when adding) at the expense of twice the storage requirements.
An alternative would be to use just a List<T>
as your basis, and verify uniqueness before any add/insert operation. This would be more memory efficient, but much slower for add/insert operations because it doesn't take advantage of a hash table.
Here's the class I used.
http://snipt.org/xlRl
The HashSet class should do the trick. See HashSet(Of T) for more information. If you need them to maintain a sorted order, the SortedSet should do the trick. See SortedSet(Of T) for more information about that class.
If you're looking to store unique objects (entities, for example) while exposing a [], then you want to use the KeyedCollection class.
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;
}
}
精彩评论