2008-10-09 3 views
55

Co chciałbym uniknąć:Najszybsza Konwersja z kolekcji do listy <T>

ManagementClass m = new ManagementClass("Win32_LogicalDisk"); 

ManagementObjectCollection managementObjects = m.GetInstances(); 

List<ManagementObject> managementList = new List<ManagementObject>(); 

foreach(ManagementObject m in managementObjects){ 

    managementList.Add(m); 

} 

nie istnieje sposób, aby uzyskać tę kolekcję w liście, który wygląda mniej więcej tak:

List<ManagementObject> managementList = new List<ManagementObjec>(collection_array); 
+0

Proszę powiedzieć nam, które ramy, które używasz. 2.0 ma inne rozwiązanie niż 3.5 – MagicKat

Odpowiedz

105

jaka wersja ram? Z 3.5 można przypuszczalnie użyć:

List<ManagementObject> managementList = managementObjects.Cast<ManagementObject>().ToList(); 

(edytowany usunąć prostszą wersję; Sprawdziłem i ManagementObjectCollection realizuje tylko nierodzajową IEnumerable formie)

+0

Twoja obsada może się nie powieść, potrzebujesz zamiast tego ManagementBaseObject. – mancaus

+0

Nie, jeśli chcemy utworzyć listę , nie robimy tego. Być może OfType byłoby rozsądnym kompromisem? –

+0

jak obsłużyć kolekcję obiektów zarządzania do IEnumerable > gdzie propertydata to sama nazwa i wartość? – Nisha

1

Możesz spróbować:

List<ManagementObject> managementList = new List<ManagementObject>(managementObjects.ToArray()); 

Nie jestem pewien, czy .ToArray() jest dostępna do kolekcji. Jeśli używasz kod pisał, upewnij się zainicjować listy z liczbą istniejących elementów:

List<ManagementObject> managementList = new List<ManagementObject>(managementObjects.Count); // or .Length 
+4

Nie, nie ma .ToArray() –

0

Dopóki ManagementObjectCollection implementuje IEnumerable <ManagementObject> można zrobić :

List<ManagementObject> managementList = new List<ManagementObjec>(managementObjects); 

Jeśli nie, to utkniesz w taki sposób, w jaki to robisz.

+1

Problem polega na tym, że nie; implementuje tylko ICollection, IEnumerable, IDisposable –

+0

@Marc Gravell: Potem utknął robiąc to tak, jak on to robi. Itercjonalnyctor robi właściwie to samo. – MagicKat

+0

Nie z .NET 3.5, nie jest. –

2

managementObjects.Cast<ManagementBaseObject>().ToList(); to dobry wybór.

Można zwiększyć wydajność sprzed inicjalizacji pojemności listy:


    public static class Helpers 
    { 
     public static List<T> CollectionToList<T>(this System.Collections.ICollection other) 
     { 
      var output = new List<T>(other.Count); 

      output.AddRange(other.Cast<T>()); 

      return output; 
     } 
    } 
+1

W rzeczywistości wstępne inicjowanie pojemności nie zaoszczędzi ci ogromnego czasu. Lista będzie rosnąć ze strategią podwójną, więc nie będzie musiała wielokrotnie zmieniać rozmiaru. Mniej kodu do utrzymania. –

+0

(zwłaszcza w porównaniu do kosztów ogólnych IEnumeable i bloku iteratora Casta ...) –

0

można konwertować jak poniżej fragment kodu

Collection<A> obj=new Collection<return ListRetunAPI()> 
0

Od 3,5, cokolwiek odziedziczone System.Collection.IEnumerable ma dostępna jest wygodna metoda rozszerzenia OfType.

Jeśli kolekcja pochodzi z kolekcji ICollection lub IEnumerable, można po prostu to zrobić:

List<ManagementObject> managementList = ManagementObjectCollection.OfType<ManagementObject>().ToList(); 

nie można znaleźć żadnych sposób prostszy. :)

+0

[OfType vs Cast] (https://stackoverflow.com/q/4015930/1997232). – Sinatr

29

Można użyć

using System.Linq; 

To daje ToList < metody> przedłużacz do kolekcji ICollection <>

+7

Ciągle uderzam w tę kwestię - "Dlaczego nie ma" ToList() ""? .... Google .... DOH! Nigdy nie wydaje mi się, aby pamiętać o włączeniu 'using System.Linq;' – Rick

+0

To prawdopodobnie powinna być akceptowana odpowiedź. –

+0

Nie ma toList() w ObjectCollection. – joaocarlospf