2010-03-29 11 views
12

Sto utilizzando un Dictionary<int, MyType> in una classe. Quella classe implementa un'interfaccia che richiede un IList<MyType> da restituire. C'è un modo semplice per trasmettere l'uno all'altro (senza copiare l'intera cosa)?Convertire dizionario <MyType> .ValueCollection a IList <MyType>

mia soluzione corrente segue:

private IList<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection) 
{ 
    List<MyType> list = new List<MyType>(); 
    list.AddRange(valueCollection); 
    return list; 
} 
+0

Ogni soluzione pubblicata fino ad ora richiede la copia dell'intera collezione. ** Leggi la domanda **. – SLaks

+0

@SLaks: l'ho indirizzato direttamente nella mia risposta ... (che comunque comporta la copia, però) –

+0

C'è qualche rilevanza per il keyType "int", o è un tipo arbitrario? –

risposta

20

Dovrai fare una copia, ma probabilmente è una buona cosa. In C# 2, il codice corrente è quasi il più pulito possibile. Sarebbe migliorato costruendo direttamente la tua lista dai tuoi valori (List<MyType> list = new List<MyType>(valueCollection);), ma sarà comunque necessaria una copia.

utilizzando LINQ con C# 3, tuttavia, si sarebbe in grado di fare:

myDictionary.Values.ToList(); 

Detto questo, non vorrei (probabilmente) cercare di evitare la copia. Restituire una copia dei tuoi valori tende ad essere più sicuro, poiché impedisce al chiamante di causare problemi nel tentativo di modificare la tua raccolta. Restituendo una copia, il chiamante può eseguire list.Add(...) o list.Remove(...) senza causare problemi di classe.


Edit: Dato il tuo commento qui sotto, se invece si è un IEnumerable<T> con un conte, si può semplicemente tornare ICollection<T>. Questo è direttamente implementato da ValueCollection, il che significa che si può semplicemente restituire i valori del vostro dizionario direttamente, senza la copia:

private ICollection<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection) 
{ 
    return valueCollection; 
} 

(Certo, questo metodo diventa davvero inutile in questo caso - ma volevo dimostrare per tu ...)

+0

@Slaks: da qui la frase successiva: "Puoi costruire direttamente l'elenco dai tuoi valori,";) Non è molto meglio, anche se dal momento che è un ICollection , sarà più efficiente (dal momento che il conteggio è noto in anticipo). –

+0

@Slaks: meglio? L'ho reso più esplicito. –

+0

Grazie per l'eccellente risposta. L'interfaccia ICollection si adatta perfettamente alle mie esigenze. –

0

È possibile utilizzare il costruttore: (. A cura di rimuovere un'asserzione non sono sicuro al 100% su)

public IList<MyType> MyValues 
{ 
    get { return new List<MyType>(myDictionary.Values); } 
} 

+0

Ciò crea ancora una copia della raccolta. – mcNux

4

Come A proposito di

Dictionary<int, MyType> dlist = new Dictionary<int, MyType>(); 
IList<MyType> list = new List<MyType>(dlist.Values); 
+2

Questo copia ancora la raccolta. – SLaks

2

Questo non è possibile.

Un dizionario (compresa la raccolta) è una raccolta non ordinata; il suo ordine cambierà in base ai codici hash delle sue chiavi. Questo è il motivo per cui ValueCollection non implementa IList<T> in primo luogo.

Se davvero volesse, si potrebbe fare una classe wrapper che implementa IList e avvolge il ValueCollection, utilizzando un ciclo foreach nel indicizzatore. Tuttavia, non è una buona idea.

+0

@SLaks Non sono schizzinoso sull'ordine. Quello che voglio è IEnumerable con un conteggio. Se c'è un'interfaccia migliore, fammi sapere. –

+0

@C. Ross: Vedi la mia modifica, poi ... –

Problemi correlati