开发者

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;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜