2010-11-02 4 views

risposta

5

Un NameValueCollection può recuperare gli elementi in base all'indice (ma non si può chiedere per l'indice di una chiave specifica o elemento). Così,

var coll = new NameValueCollection(); 
coll.Add("Z", "1"); 
coll.Add("A", "2"); 
Console.WriteLine("{0} = {1}", coll.GetKey(0), coll[0]); // prints "Z = 1" 

Tuttavia, si comporta in modo strano (a fronte di un IDictionary) quando si aggiunge un tasto più volte:

var coll = new NameValueCollection(); 
coll.Add("Z", "1"); 
coll.Add("A", "2"); 
coll.Add("Z", "3"); 
Console.WriteLine(coll[0]); // prints "1,3" 

Il comportamento è ben documentato, tuttavia.

Attenzione: NameValueCollection fa non attrezzo IDictionary.


Per inciso: Dictionary<K,V> non ha alcun indice è possibile utilizzare, ma finché si aggiungono solo elementi, e mai rimuovere qualsiasi, l'ordine degli elementi è l'ordine di inserimento. Si noti che questo è un dettaglio dell'attuale implementazione di Microsoft: la documentazione afferma esplicitamente che l'ordine è casuale, quindi questo comportamento può cambiare nelle versioni future di .NET Framework o Mono.

+0

questo è grande. Un'alternativa a Hashtable e Dictionary che è semplice. Inoltre, la nota sull'ordinamento predefinito del dizionario è molto utile. –

+0

Ricordarsi di aggiungere: usando System.Collections.Specialized; –

5

Se si tratta di qualcosa che è necessario tenere traccia in modo efficiente, si utilizza la struttura dati errata. Invece, dovresti utilizzare uno SortedDictionary in cui la chiave è contrassegnata con l'indice di quando è stato aggiunto (o un timestamp) e un numero personalizzato IComparer che confronta due chiavi in ​​base all'indice (o al timestamp).

3

C'è qualche Hashtable o dizionario in .NET che ti consente di accedere alla sua proprietà .Index per la voce nell'ordine in cui è stata aggiunta alla raccolta?

No. Si può enumarate su tutti gli elementi di una Hastable o un dizionario, ma questi non sono gaurenteed di essere in qualsiasi tipo di ordine (molto probabilmente non lo sono)

sarebbe necessario sia per uso una diversa struttura di dati del tutto, (come SortedDictionary o SortedList) o utilizzare una lista separata per memorizzare l'ordine in cui sono stati aggiunti. Si vorrebbe avvolgere la lista ordinata e il dizionario/tabella hash in un'altra classe per mantenerli sincronizzati.

3

È possibile utilizzare un elenco separato per memorizzare gli elementi nell'ordine in cui sono stati aggiunti. Qualcosa sulla falsariga del seguente esempio:

public class ListedDictionary<TKey, TValue> : IDictionary<TKey, TValue> 
{ 
    List<TValue> _list = new List<TValue>(); 
    Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey,TValue>(); 

    public IEnumerable<TValue> ListedValues 
    { 
     get { return _list; } 
    } 

    public void Add(TKey key, TValue value) 
    { 
     _dictionary.Add(key, value); 
     _list.Add(value); 
    } 

    public bool ContainsKey(TKey key) 
    { 
     return _dictionary.ContainsKey(key); 
    } 

    public ICollection<TKey> Keys { get { return _dictionary.Keys; } } 

    public bool Remove(TKey key) 
    { 
     _list.Remove(_dictionary[key]); 
     return _dictionary.Remove(key); 
    } 

    // further interface methods... 
} 
1

Un'alternativa è quella di creare un array di Costruzioni, così invece di utilizzare

dictionary.Add{"key1","value1"} 

si crea una struttura con la chiave/valore come:

public struct myStruct{ 
    private string _sKey; 
    public string sKey{ 
     get { return _sKey; } 
     set { _sKey = value; } 
    } 
    private string _sValue; 
    public string sValue { 
     get { return _sValue; } 
     set { _sValue = value; } 
    } 
} 

// create list here 
List<myStruct> myList = new List<myStruct>(); 

// create an instance of the structure to add to the list 
myStruct item = new myStruct(); 
item.sKey = "key1"; 
item.sValue = "value1"; 

// then add the structure to the list 
myList.Add(item); 

Usando questo metodo è possibile aggiungere in più dimensioni alla lista senza troppo sforzo, basta aggiungere un nuovo membro nella struttura.

nota, se è necessario modificare gli elementi nella lista dopo che sono stati aggiunti si dovrà cambiare la struct in una classe. Vedere questa pagina per maggiori informazioni su questo tema: error changing value of structure in a list

2

Date un'occhiata alla classe OrderedDictionary. Non solo puoi accedervi tramite i tasti, ma anche tramite un indice (posizione).

Problemi correlati