2010-03-29 7 views
12

Ich benutze eine Dictionary<int, MyType> in einer Klasse. Diese Klasse implementiert eine Schnittstelle, die eine Rückgabe von IList<MyType> erfordert. Gibt es einen einfachen Weg, den einen auf den anderen zu werfen (ohne das Ganze zu kopieren)?Konvertieren Wörterbuch <MyType> .ValueCollection zu IList <MyType>

Meine aktuelle Lösung folgt:

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

Jede bisher veröffentlichte Lösung beinhaltet das Kopieren der gesamten Sammlung. **Lies die Frage**. – SLaks

+0

@SLaks: Ich adressierte dies direkt in meiner Antwort ... (was immer noch beinhaltet Kopieren) –

+0

Gibt es irgendeine Relevanz für den keyType "int", oder ist es ein beliebiger Typ? –

Antwort

20

Sie müssen eine Kopie machen, aber das ist wahrscheinlich eine gute Sache. In C# 2 ist Ihr aktueller Code fast der sauberste, den Sie erstellen können. Es würde verbessert werden, indem Sie Ihre Liste direkt von Ihren Werten aufbauen (List<MyType> list = new List<MyType>(valueCollection);), aber eine Kopie wird immer noch benötigt.

LINQ Verwendung mit C# 3, jedoch würden Sie in der Lage zu tun:

myDictionary.Values.ToList(); 

aber sagen, dass ich nicht (wahrscheinlich) versuchen, die Kopie zu vermeiden. Die Rückgabe einer Kopie Ihrer Werte ist tendenziell sicherer, da sie verhindert, dass der Aufrufer Probleme verursacht, wenn er versucht, Ihre Sammlung zu ändern. Durch das Zurückgeben einer Kopie kann der Aufrufer list.Add(...) oder list.Remove(...) tun, ohne Ihre Klassenprobleme zu verursachen.


Edit: Da Sie Ihren Kommentar unten, wenn alles, was Sie wollen, ist ein IEnumerable<T> mit einem Grafen, können Sie einfach ICollection<T> zurück. Diese wird direkt von ValueCollection implementiert, was bedeutet, dass Sie nur direkt Ihr Wörterbuch des Wert zurückgeben können, ohne das Kopieren:

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

(Zugegeben, das Verfahren in diesem Fall wirklich nutzlos wird - aber ich wollte es zeigen, für Sie ...)

+0

@Slaks: Daher der nächste Satz: "Sie können Ihre Liste direkt von Ihren Werten aufbauen,";) Das ist nicht viel besser, obwohl, da es eine ICollection ist, es effizienter sein wird (da count im Voraus bekannt ist). –

+0

@Slaks: Das besser? Ich habe es deutlicher gemacht. –

+0

Danke für die ausgezeichnete Antwort. Die ICollection-Schnittstelle passt perfekt zu meinen Bedürfnissen. –

0

Sie den Konstruktor verwenden: (. Edited sicher auf eine Behauptung Ich bin nicht 100% entfernen)

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

+0

Dies erstellt immer noch eine Kopie der Sammlung. – mcNux

4

Wie über

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

Dies kopiert immer noch die Sammlung. – SLaks

2

Dies ist nicht möglich.

Ein Wörterbuch (einschließlich seiner Values Sammlung) ist eine inhärent ungeordnete Sammlungen; seine Reihenfolge ändert sich basierend auf den Hashcodes seiner Schlüssel. Aus diesem Grund implementiert ValueCollection nicht IList<T> an erster Stelle.

Wenn Sie wirklich wollten, könnten Sie eine Wrapper-Klasse machen, die IList implementiert und hüllt den ValueCollection, eine foreach Schleife in der Indexer verwenden. Es ist jedoch keine gute Idee.

+0

@SLaks Ich bin nicht wählerisch über die Bestellung. Was ich will ist IEnumerable mit einer Zählung. Wenn es eine bessere Schnittstelle gibt, lass es mich wissen. –

+0

@C. Ross: Siehe meine Bearbeitung, dann ... –

Verwandte Themen