Es scheint, dass List<T>
in C # alles möglich ist, was ein Array kann, und dass es in Bezug auf Speicher und Leistung genauso effizient ist wie ein Array.
Warum sollte ich jemals ein Array verwenden wollen?
Ich frage offensichtlich nicht nach Fällen, in denen ich aufgrund einer API oder einer anderen externen Einschränkung (dh der Hauptfunktion) ein Array verwenden muss. Ich frage nur nach der Erstellung neuer Datenstrukturen in meinem eigenen Code.
c#
data-types
JoelFan
quelle
quelle
List<T>
is also just as efficient in memory and performance as an array
- ähm. Woher hast du diese Vorstellung?var test = new string[5,5]
;)Antworten:
Aus demselben Grund fahre ich keinen LKW, wenn ich zur Arbeit gehe. Ich verwende nichts, wofür ich die Funktionen von nicht verwende.
Erstens ist ein Array ein primitives Konstrukt, daher ist ein Array mit Sicherheit schneller und effizienter als eine List <>, sodass Ihr Argument nicht wahr ist. Array ist auch überall verfügbar und Entwicklern bekannt, die verschiedene Sprachen und Plattformen verwenden.
Der wichtigste Grund, warum ich ein Array anstelle einer Liste <> verwende, besteht darin, dass die Daten eine feste Länge haben . Wenn ich dieser Datenerfassung keine Elemente hinzufügen oder daraus entfernen möchte, möchte ich sicherstellen, dass der Typ dies widerspiegelt.
Angenommen, Sie implementieren eine neue Datenstruktur und haben einige Artikel darüber gelesen. Während Sie bestimmte Algorithmen implementieren, können Sie sich nicht immer auf die Implementierung eines allgemeinen Typs durch eine andere Person verlassen. Es wechselt von .NET zu Mono und sogar zwischen verschiedenen Versionen des Frameworks.
Manchmal ist es auch einfacher, einen Code zu portieren, der ein Array anstelle eines Framework-abhängigen Typs verwendet.
quelle
List<T>
es mithilfe eines Arrays implementiert wird? Wenn Sie die Anzahl der Elemente im Voraus kennen (was Sie wissen müssen, wenn Sie ein Array verwenden), können Sie diese Kenntnisse auch beim Initialisieren der Liste verwenden.Natürlich benötigen Sie Arrays, um Ihre Sammlung veränderlicher Strukturen zu verwalten , und was würden wir ohne diese tun ?
(Beachten Sie, dass es einige Fälle geben kann, in denen ein Array mit veränderlichen Strukturen wünschenswert ist. In der Regel ist dieses unterschiedliche Verhalten von veränderlichen Strukturen in Arrays im Vergleich zu anderen Auflistungen jedoch eine Fehlerquelle, die vermieden werden sollte.)
Im Ernst, Sie benötigen ein Array, wenn Sie ein Element als Referenz übergeben möchten . dh
Dies kann für sperrenfreien Thread-Safe-Code hilfreich sein.
Sie benötigen ein Array, wenn Sie Ihre Sammlung mit fester Größe schnell und effizient mit dem Standardwert initialisieren möchten .
(Beachten Sie, dass es möglich wäre, einen Konstruktor für List zu implementieren, der dasselbe tut. Es ist nur so, dass c # diese Funktion nicht bietet.)
Sie benötigen ein Array, um Teile der Sammlung effizient zu kopieren
(Auch dies ist etwas, das für List ebenfalls implementiert werden könnte, aber diese Funktion ist in c # nicht vorhanden.)
quelle
In seltenen Fällen haben Sie ein Szenario, in dem Sie wissen, dass Sie eine feste Anzahl von Elementen benötigen. Aus gestalterischer Sicht sollte dies vermieden werden. Wenn Sie drei Dinge benötigen, bedeutet die Art des Geschäfts, dass Sie in der nächsten Version sehr oft vier benötigen.
Wenn dieses seltene Szenario tatsächlich auftritt, ist es dennoch nützlich, ein Array zum Erzwingen dieser Invariante mit fester Größe zu verwenden. Es gibt anderen Programmierern ein Signal, dass es eine feste Größe hat, und hilft, Missbrauch zu verhindern, wenn jemand ein Element hinzufügt oder entfernt - was die Erwartungen an anderer Stelle im Code verletzt.
quelle
Ihre Frage wurde tatsächlich schon einmal beantwortet .
Ist es nicht. Aus der Frage, die ich verlinkt habe:
Arrays sind in bestimmten wichtigen Fällen doppelt so schnell. Ich bin mir sicher, dass sich die Speichernutzung auch nicht trivial unterscheidet.
Da die Hauptprämisse Ihrer Frage damit besiegt ist, gehe ich davon aus, dass dies Ihre Frage beantwortet. Darüber hinaus werden Arrays manchmal von der Win32-API, dem Shader Ihrer GPU oder einer anderen Nicht-DotNet-Bibliothek erzwungen.
Sogar innerhalb von DotNet verbrauchen einige Methoden Arrays und / oder geben sie zurück (z. B.
String.Split
). Das heißt, entweder müssen Sie jetzt die Kosten für das Anrufen essenToList
und dieToArray
ganze Zeit aufbrauchen müssen, oder dass Sie das Array anpassen und verwenden müssen, um möglicherweise den Zyklus fortzusetzen, indem Sie dies an arme nachgeschaltete Benutzer Ihres Codes weitergeben.Weitere Fragen und Antworten zu Stack Overflow zu diesem Thema:
List<T>
: Wann soll welches verwendet werden?List<>
?quelle
Zusätzlich zu den in anderen Antworten aufgeführten Gründen benötigt das Array-Literal weniger Zeichen für die Deklaration:
Durch die Verwendung von array anstelle von
List
wird der Code etwas kürzer und nur in Fällen, in denen Sie (1) any übergeben müssen, etwas besser lesbarIEnumerable<T>
Literal übergeben müssen oder (2) wenn andere FunktionenList
keine Rolle spielen und Sie einige listenähnliche Funktionen verwenden müssen wörtlich.Ich habe das gelegentlich in Unit-Tests gemacht.
quelle
foreach( var x in new []{ a, b, c ) ) DoStuff( x )
odernew []{ a, b, c ).Select( ... )
etcDies ist streng aus OO-Sicht.
Ich kann mir zwar keinen Grund vorstellen, nur ein Array weiterzugeben, aber ich kann durchaus Situationen erkennen, in denen eine Array-Darstellung innerhalb der Klasse wahrscheinlich die beste Wahl ist.
Obwohl es andere Optionen gibt, die ähnliche Eigenschaften aufweisen, scheint keine so intuitiv zu sein wie ein Array für Probleme bei der Verarbeitung von Permutationen, verschachtelt für Schleifen, Matrixdarstellung, Bitmaps und Datenverschachtelungsalgorithmen.
Es gibt eine beträchtliche Anzahl wissenschaftlicher Gebiete, die sich weitgehend auf Matrixmathematik stützen. (z. B. Bildverarbeitung, Datenfehlerkorrektur, digitale Signalverarbeitung, eine Unmenge angewandter mathematischer Probleme). Die meisten Algorithmen in diesen Feldern sind im Hinblick auf die Verwendung mehrdimensionaler Arrays / Matrizen geschrieben. Daher wäre es natürlicher, die Algorithmen so zu implementieren, wie sie definiert sind, als sie "softwarefreundlicher" zu gestalten, und zwar auf Kosten des Verlusts der direkten Verbindungen zu den Papieren, auf denen die Algorithmen basieren.
Wie ich bereits sagte, kann man in diesen Fällen wahrscheinlich mit der Verwendung von Listen davonkommen, aber das fügt zusätzlich zu den bereits komplexen Algorithmen noch eine weitere Komplexitätsebene hinzu.
quelle
Dies gilt auch für andere Sprachen, die Listen enthalten (z. B. Java oder Visual Basic). Es gibt Fälle, in denen Sie ein Array verwenden müssen, weil eine Methode ein Array anstelle einer Liste zurückgibt.
Ich glaube nicht, dass ein Array in einem tatsächlichen Programm sehr oft verwendet wird, aber manchmal wissen Sie, dass die Daten eine feste Größe haben und Sie mögen den geringen Leistungsgewinn, den Sie durch die Verwendung eines Arrays erzielen. Mikrooptimierung wäre ein triftiger Grund, genauso wie eine Methode, die eine Liste zurückgibt, oder die Notwendigkeit einer mehrdimensionalen Datenstruktur.
quelle
list<T>
demvector<T>
Willen Arbeit eine katastrophal schlechte Idee in C / C ++ ist.vector<T> x
für mich in C ganz gut kompiliert . :-)list<T>
. Grundsätzlich habe ich viele Leistungsprobleme gesehen, die von Entwicklern verursacht wurden, die standardmäßig nur Listen verwendeten, als ein Array die bessere Wahl war.Nun, ich habe eine Verwendung für Arrays in einem Spiel gefunden, das ich geschrieben habe. Ich habe es zum Erstellen eines Inventarsystems mit einer festen Anzahl von Slots verwendet. Dies hatte mehrere Vorteile:
Ich stellte mir vor, dass ich das Inventar "vergrößern" könnte, wenn ich es jemals "vergrößern" müsste, indem ich die alten Elemente in das neue Array übertrage. Da das Inventar jedoch durch den Bildschirmbereich festgelegt wurde, musste ich es nicht dynamisch vergrößern / kleiner, es funktionierte gut für den Zweck, für den ich es benutzte.
quelle
Wenn Sie alle Elemente einer Liste durchlaufen, ist kein Array erforderlich. Die Option "Nächste" oder "Beliebige Auswahl ohne Ersetzung" reicht aus.
Wenn Ihr Algorithmus jedoch zufälligen Zugriff auf die Elemente in der Auflistung benötigt, ist ein Array erforderlich.
Dies ist in gewisser Weise analog zu "ist es notwendig?". In einer vernünftigen modernen Sprache wird es überhaupt nicht benötigt. Wenn Sie die Abstraktionen jedoch irgendwann entfernen, ist dies alles, was Ihnen tatsächlich zur Verfügung steht. Das heißt, die einzige Möglichkeit, diese Abstraktionen zu implementieren, besteht in der "unnötigen" Funktion. (Natürlich ist die Analogie nicht perfekt, ich glaube nicht, dass jemand sagt, dass Arrays eine schlechte Programmierpraxis sind; sie sind einfach zu verstehen und zu überlegen).
quelle
List<T>
.Legacy-Kompatibilität.
Alles aus persönlicher Erfahrung:
Legacy-Programmierer - mein Kollege verwendet Arrays überall, hat über 30 Jahre lang gute Arbeit geleistet und seine Meinung durch Ihre neuen Ideen geändert.
Legacy-Code - foo (Array-Leiste []) Sie können zwar eine Listen- / Vektor- / Sammlungs-Array-Funktion verwenden, aber wenn Sie keine der zusätzlichen Funktionen verwenden, ist es einfacher, zunächst ein Array zu verwenden, das häufig ohne Typumschaltung besser lesbar ist.
Legacy-Chef - mein Chef war ein guter Programmierer, bevor sie vor vielen Jahren in die Geschäftsführung eingetreten ist, und denkt immer noch, dass sie auf dem neuesten Stand ist. "Arrays verwenden" kann ein Meeting beenden und erklären, was eine Sammlung jeden das Mittagessen kostet.
quelle
1) Es gibt keine mehrdimensionale Version von List. Wenn Ihre Daten mehr als eine Dimension haben, ist die Verwendung von Listen sehr ineffizient.
2) Wenn Sie mit einer großen Anzahl kleiner Datentypen zu tun haben (z. B. eine Karte, bei der Sie nur ein Byte für den Geländetyp haben), kann es aufgrund des Cachings zu erheblichen Leistungsunterschieden kommen. Die Array-Version lädt mehrere Elemente pro gelesenem Speicher, die Listenversion lädt nur ein Element. Darüber hinaus enthält die Array-Version mehrmals so viele Zellen im Cache wie die Listenversion. Wenn Sie die Daten wiederholt verarbeiten, kann dies einen großen Unterschied bewirken, wenn die Array-Version in den Cache passt, die Listenversion jedoch nicht.
Betrachten Sie für einen extremen Fall Minecraft. (Ja, es ist nicht in C # geschrieben. Der gleiche Grund gilt.)
quelle
T[,]
) sind langsamer als die entsprechenden gezackten Arrays (zT[][]
. B. ) .Ein Array mit 100 Elementen eines Typs T kapselt 100 unabhängige Variablen des Typs T. Wenn T zufällig ein Werttyp ist, der ein veränderbares öffentliches Feld des Typs Q und eines des Typs R aufweist, kapselt jedes Element des Arrays unabhängige Variablen von Typen Q und R. Das Array als Ganzes wird somit 100 unabhängige Variablen vom Typ Q und 100 unabhängige Variablen vom Typ R einkapseln; Auf jede dieser Variablen kann einzeln zugegriffen werden, ohne dass sich dies auf eine andere auswirkt. Kein anderer Auflistungstyp als Arrays kann zulassen, dass die Felder von Strukturen als unabhängige Variablen verwendet werden.
Wenn T stattdessen ein Klassentyp mit öffentlichen veränderlichen Feldern vom Typ Q und R ist, enthält jedes Element des Arrays an einer beliebigen Stelle im Universum den einzigen Verweis auf eine Instanz , die ein Array oder eine Sammlung von veränderlichen Klassentypen verwendet, wodurch die Möglichkeit geschaffen wird dass die durch Array-Elemente identifizierten Variablen möglicherweise nicht unabhängig sind .
T
und falls keines der Elemente des Arrays jemals wird modifiziert werden, um ein Objekt zu identifizieren, für das ein externer Verweis vorhanden ist, kapselt das Array effektiv 100 unabhängige Variablen des Typs Q und 100 unabhängige Variablen des Typs R. Andere Auflistungstypen können das Verhalten eines solchen Arrays imitieren, wenn dies jedoch der einzige Zweck ist Das Einkapseln von 100 Variablen des Typs Q und 100 Variablen des Typs R in ein eigenes Klassenobjekt ist eine teure Methode. Des Weiteren,Wenn sich ein Typ wie ein Objekt verhalten soll, sollte es sich entweder um einen Klassentyp oder eine Private-Field-Struktur handeln, die keine andere Möglichkeit der Mutation bietet als das Ersetzen. Wenn jedoch ein Typ wie ein Haufen von verwandten , aber unabhängig verhalten soll Variablen stecken zusammen mit Klebeband, dann sollte man eine Art verwenden , das ist ein Bündel von Variablen zusammen mit Klebeband geklebt - eine exponierter-Feld - Struktur . Arrays dieser Art sind sehr effizient und haben eine sehr saubere Semantik. Die Verwendung eines anderen Typs führt zu einer verwirrten Semantik, schlechter Leistung oder beidem.
quelle
Ein wichtiger Unterschied ist die Speicherzuweisung. Das Durchlaufen einer verknüpften Liste kann beispielsweise zu vielen Cache-Fehlern und einer langsameren Leistung führen, wohingegen ein Array einen zusammenhängenden Teil des Speichers darstellt, der mehrere Instanzen eines bestimmten Datentyps enthält, und das Durchlaufen in der Reihenfolge, in der die CPU mit größerer Wahrscheinlichkeit betroffen ist Zwischenspeicher.
Natürlich kann ein Array von Objektreferenzen nicht so stark von Cache-Treffern profitieren, da die Dereferenzierung Sie immer noch an eine beliebige Stelle im Speicher bringen kann.
Dann gibt es Listenimplementierungen wie ArrayList, die eine Liste mithilfe eines Arrays implementieren. Sie sind nützliche Primitive.
quelle
List<T>
, der nicht über eine verknüpfte Liste, sondern über ein Array implementiert wird (entsprichtArrayList<T>
im Wesentlichen Java).Hier einige Anleitungen, die Sie verwenden können, um wann
Array
und wann auszuwählenList
.Array
wenn Sie von einer Methode zurückkehren.List
als Variable verwendet, wenn Sie den Rückgabewert (innerhalb der Methode) erstellen. Verwenden Sie dann,.ToArray()
wenn Sie von der Methode zurückkehren.Verwenden
Array
Sie im Allgemeinen eine, wenn Sie nicht beabsichtigen, der Sammlung Elemente hinzuzufügen. VerwendenList
Sie diese Option, wenn Sie möchten, dass der Konsument der Sammlung Elemente hinzufügt.Array
ist für den Umgang mit "statischen" SammlungenList
gedacht, während es für den Umgang mit "dynamischen" Sammlungen gedacht ist.quelle
Array
vonList
. Schön deine Gedanken zu hören!