Collections Referenz
In C# sind Collections Referenzen essenzielle Strukturen für die Verwaltung und Verarbeitung von Objektsammlungen im Speicher. Im Gegensatz zu Werttypen speichern Referenz-Collections Objekte auf dem Heap, was eine flexible und dynamische Handhabung von Daten ermöglicht. Sie sind unverzichtbar für die Entwicklung moderner Anwendungen, die große oder komplexe Datensätze effizient verarbeiten müssen, wie z.B. Benutzerlisten, Bestellungen oder Ereignisstreams in Echtzeit. Die richtige Anwendung von Referenz-Collections, wie List
Referenz-Collections greifen direkt auf Kernkonzepte von C# zurück, darunter strikte Syntax, leistungsfähige Datenstrukturen, effiziente Algorithmen und Prinzipien der objektorientierten Programmierung. Sie ermöglichen komplexe Operationen wie Sortierung, Suche oder Datenflusssteuerung innerhalb von Architekturen auf Unternehmensniveau. Das Verständnis dieser Collections ist entscheidend, um Speicherlecks zu vermeiden, Fehlerquellen zu reduzieren und eine konsistente Datenmanipulation sicherzustellen.
Dieses Referenzdokument vermittelt praxisnah, wie man Referenz-Collections erstellt, modifiziert und optimiert, sowie ihre Vor- und Nachteile erkennt. Leser lernen Best Practices, Performance-Tipps und die Integration von Collections in Design Patterns. Dadurch werden C#-Entwickler in die Lage versetzt, skalierbare, modulare und wartbare Systeme zu bauen und algorithmische Probleme effizient zu lösen.
Grundlegendes Beispiel
textusing System;
using System.Collections.Generic;
namespace CollectionsReferenzExample
{
class Program
{
static void Main(string\[] args)
{
// Erstellen einer Liste von Strings
List<string> obst = new List<string> { "Apfel", "Banane", "Kirsche" };
// Hinzufügen eines Elements
obst.Add("Orange");
// Zugriff und Modifikation
obst[1] = "Mango";
// Iteration über die Collection
Console.WriteLine("Liste der Früchte:");
foreach (string frucht in obst)
{
Console.WriteLine(frucht);
}
// Überprüfung eines Elements
if (obst.Contains("Kirsche"))
{
Console.WriteLine("Kirsche ist in der Liste vorhanden.");
}
}
}
}
Das obige Beispiel demonstriert den Einsatz von List
Die foreach-Schleife ermöglicht eine sichere und übersichtliche Iteration über die Elemente, wodurch Indexierungsfehler vermieden werden. Die Methode obst.Contains("Kirsche") veranschaulicht die Suche innerhalb der Collection mittels eines optimierten internen Algorithmus. Dieses Beispiel zeigt außerdem Best Practices: Verwendung generischer Typen für Typsicherheit, keine manuelle Speicherverwaltung erforderlich dank Garbage Collector und klare, wartbare Syntax.
In praktischen Projekten kommen solche Collections für dynamische Datenmengen wie Benutzerlisten, Eventstreams oder Produktkataloge zum Einsatz. Jedes Element ist ein Objekt, wodurch die Prinzipien der objektorientierten Programmierung wie Kapselung und Modularität effektiv unterstützt werden. Dies bildet die Grundlage für sauberen, skalierbaren und robusten C#-Code.
Praktisches Beispiel
textusing System;
using System.Collections.Generic;
namespace AdvancedCollectionsReferenz
{
class Person
{
public string Name { get; set; }
public int Alter { get; set; }
}
class Program
{
static void Main(string[] args)
{
// Erstellen eines Dictionary mit einzigartiger ID
Dictionary<int, Person> personen = new Dictionary<int, Person>();
personen.Add(1, new Person { Name = "Alice", Alter = 30 });
personen.Add(2, new Person { Name = "Bob", Alter = 25 });
personen.Add(3, new Person { Name = "Charlie", Alter = 35 });
// Sichere Suche nach einer Person anhand der ID
if (personen.TryGetValue(2, out Person gefunden))
{
Console.WriteLine($"Gefundene Person: {gefunden.Name}, {gefunden.Alter} Jahre");
}
// Iteration über das Dictionary
foreach (var eintrag in personen)
{
Console.WriteLine($"ID: {eintrag.Key}, Name: {eintrag.Value.Name}");
}
// Sichere Entfernung eines Eintrags
personen.Remove(3);
}
}
}
Advanced C# Implementation
textusing System;
using System.Collections.Generic;
using System.Linq;
namespace EnterpriseCollectionsReferenz
{
class Produkt
{
public string Name { get; set; }
public decimal Preis { get; set; }
}
class Program
{
static void Main(string[] args)
{
try
{
// HashSet zur Vermeidung von Duplikaten
HashSet<Produkt> produkte = new HashSet<Produkt>(new ProduktComparer())
{
new Produkt { Name = "Laptop", Preis = 1200 },
new Produkt { Name = "Tablet", Preis = 450 },
new Produkt { Name = "Laptop", Preis = 1200 } // wird ignoriert
};
// LINQ für Filterung und Sortierung
var teureProdukte = produkte
.Where(p => p.Preis > 500)
.OrderByDescending(p => p.Preis)
.ToList();
foreach (var produkt in teureProdukte)
{
Console.WriteLine($"Produkt: {produkt.Name}, Preis: {produkt.Preis}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Fehler: {ex.Message}");
}
}
}
class ProduktComparer : IEqualityComparer<Produkt>
{
public bool Equals(Produkt x, Produkt y)
{
return x.Name == y.Name && x.Preis == y.Preis;
}
public int GetHashCode(Produkt obj)
{
return obj.Name.GetHashCode() ^ obj.Preis.GetHashCode();
}
}
}
Die praktischen Beispiele zeigen erweiterte Konzepte der Referenz-Collections in C#. Das Dictionary ermöglicht schnelle Zugriffe über eindeutige Schlüssel mit TryGetValue, während HashSet Duplikate verhindert und LINQ für Filterung und Sortierung nutzt. ProduktComparer illustriert die Anpassung von Vergleichsfunktionen für Objekte, um Datenintegrität zu gewährleisten.
Best Practices umfassen: exception handling mittels try-catch, generische Typen für Typsicherheit, LINQ zur Optimierung von Collection-Operationen. Die Wahl der richtigen Collection (List
C# Best Practices und Fallstricke
text// Best Practices und häufige Fehler
* Generische Collections nutzen für Typsicherheit und Vermeidung unnötiger Casts
* Auswahl der richtigen Datenstruktur: List<T>, Dictionary\<TKey,TValue>, Queue<T>, Stack<T>, HashSet<T>
* Exceptions bei Collection-Manipulationen abfangen
* foreach für sichere Iterationen bevorzugen
* Verschachtelte Schleifen minimieren zur Optimierung
* LINQ gezielt verwenden, besonders bei großen Collections
* Nicht benötigte Referenzen entfernen, Garbage Collector freigeben lassen
* Performance bei großen Collections testen
* Threadsicherheit bei parallelen Zugriffen beachten (Concurrent Collections)
* Eigene Comparer für HashSet und Dictionary implementieren zur Datenintegrität
📊 Umfassende Referenz
C# Element/Method | Description | Syntax | Example | Notes |
---|---|---|---|---|
List<T> | Dynamische, geordnete Collection | List<int> zahlen = new List<int>(); | zahlen.Add(10); | Indexierter Zugriff, automatische Größenerweiterung |
List<T>.Add() | Fügt ein Element hinzu | zahlen.Add(10); | zahlen.Add(5); | O(1) durchschnittlich |
List<T>.Remove() | Entfernt ein Element | zahlen.Remove(10); | zahlen.Remove(5); | Gibt true zurück wenn erfolgreich |
List<T>.Contains() | Überprüft Element | zahlen.Contains(10); | bool vorhanden = zahlen.Contains(5); | Lineare Suche |
List<T>.Count | Anzahl der Elemente | zahlen.Count | int total = zahlen.Count; | Aktualisiert dynamisch |
Dictionary\<TKey,TValue> | Schlüssel-Wert Collection | Dictionary\<int,string> dict = new Dictionary\<int,string>(); | dict.Add(1,"Alice"); | Schneller Zugriff über Schlüssel |
Dictionary\<TKey,TValue>.Add() | Fügt Schlüssel-Wert-Paar hinzu | dict.Add(1,"Alice"); | dict.Add(2,"Bob"); | Exception bei doppeltem Schlüssel |
Dictionary\<TKey,TValue>.TryGetValue() | Sichere Wertsuche | dict.TryGetValue(2,out string val); | bool gefunden = dict.TryGetValue(1,out string name); | Vermeidet Exceptions |
Dictionary\<TKey,TValue>.Remove() | Entfernt Paar | dict.Remove(1); | dict.Remove(2); | True bei erfolgreicher Entfernung |
Dictionary\<TKey,TValue>.Keys | Schlüsselsammlung | var keys = dict.Keys; | foreach(var key in dict.Keys) | Nur-Lesezugriff |
Dictionary\<TKey,TValue>.Values | Wertekollektion | var values = dict.Values; | foreach(var val in dict.Values) | Nur-Lesezugriff |
Queue<T> | FIFO Collection | Queue<int> q = new Queue<int>(); | q.Enqueue(10); | First In First Out |
Queue<T>.Enqueue() | Hinzufügen | q.Enqueue(10); | q.Enqueue(20) | O(1) |
Queue<T>.Dequeue() | Entfernen erstes Element | q.Dequeue(); | int first = q.Dequeue(); | Exception wenn leer |
Queue<T>.Peek() | Erstes Element ansehen | q.Peek(); | int peek = q.Peek(); | Exception wenn leer |
Stack<T> | LIFO Collection | Stack<int> s = new Stack<int>(); | s.Push(10); | Last In First Out |
Stack<T>.Push() | Hinzufügen oben | s.Push(10); | s.Push(20) | O(1) |
Stack<T>.Pop() | Entfernen oben | s.Pop(); | int top = s.Pop(); | O(1), Exception wenn leer |
Stack<T>.Peek() | Oberstes Element ansehen | s.Peek(); | int top = s.Peek(); | Exception wenn leer |
HashSet<T> | Einzigartige Elemente | HashSet<int> hs = new HashSet<int>(); | hs.Add(10); | Vermeidet Duplikate |
HashSet<T>.Add() | Element hinzufügen | hs.Add(10); | hs.Add(5); | False wenn schon vorhanden |
HashSet<T>.Remove() | Element entfernen | hs.Remove(10); | hs.Remove(5); | True wenn entfernt |
HashSet<T>.Contains() | Element überprüfen | hs.Contains(10); | bool vorhanden = hs.Contains(5); | O(1) durchschnittlich |
IEnumerable<T> | Iteration Interface | IEnumerable<int> zahlen | foreach(var n in zahlen) | Basis für foreach und LINQ |
ICollection<T> | Collection Interface | ICollection<int> coll | coll.Count | Unterstützt Count, Add, Remove |
IList<T> | Listen Interface | IList<int> list | list\[0] = 10 | Indexierter Zugriff |
IReadOnlyCollection<T> | Nur-Lese Collection | IReadOnlyCollection<int> readOnly | int total = readOnly.Count | Keine Modifikation |
IReadOnlyList<T> | Nur-Lese Indexiert | IReadOnlyList<int> readOnlyList | int first = readOnlyList\[0] | Nur-Lesezugriff |
ObservableCollection<T> | Collection mit Benachrichtigung | ObservableCollection<int> oc = new ObservableCollection<int>(); | oc.CollectionChanged += Handler | Für MVVM geeignet |
ConcurrentDictionary\<TKey,TValue> | Thread-safe Dictionary | ConcurrentDictionary\<int,string> cd = new ConcurrentDictionary\<int,string>(); | cd.TryAdd(1,"A"); | Thread-sicher |
ConcurrentQueue<T> | Thread-safe Queue | ConcurrentQueue<int> cq = new ConcurrentQueue<int>(); | cq.TryDequeue(out int val); | FIFO Thread-sicher |
ConcurrentStack<T> | Thread-safe Stack | ConcurrentStack<int> cs = new ConcurrentStack<int>(); | cs.TryPop(out int val); | LIFO Thread-sicher |
SortedList\<TKey,TValue> | Sortiertes Dictionary | SortedList\<int,string> sl = new SortedList\<int,string>(); | sl.Add(1,"A"); | Automatische Sortierung |
SortedDictionary\<TKey,TValue> | Sortiertes Dictionary | SortedDictionary\<int,string> sd = new SortedDictionary\<int,string>(); | sd.Add(1,"A"); | Besser bei häufigen Insertions |
LinkedList<T> | Doppelt verkettete Liste | LinkedList<int> ll = new LinkedList<int>(); | ll.AddLast(10); | Sequenzieller Zugriff |
LinkedList<T>.AddFirst() | Anfang hinzufügen | ll.AddFirst(5); | ll.AddFirst(1) | O(1) |
LinkedList<T>.AddLast() | Ende hinzufügen | ll.AddLast(10); | ll.AddLast(20) | O(1) |
LinkedList<T>.Remove() | Element entfernen | ll.Remove(10); | ll.Remove(20) | O(n) |
LinkedList<T>.Find() | Element suchen | ll.Find(10); | var node = ll.Find(10) | Gibt LinkedListNode<T> |
Stack<T>.Clear() | Stack leeren | s.Clear(); | s.Clear() | Referenzen freigeben |
Queue<T>.Clear() | Queue leeren | q.Clear(); | q.Clear() | Referenzen freigeben |
List<T>.Clear() | Liste leeren | zahlen.Clear(); | zahlen.Clear() | Referenzen freigeben |
Dictionary\<TKey,TValue>.Clear() | Dictionary leeren | dict.Clear(); | dict.Clear() | Referenzen freigeben |
List<T>.IndexOf() | Index zurückgeben | zahlen.IndexOf(5); | int idx = zahlen.IndexOf(5) | -1 wenn nicht vorhanden |
ArrayList | Nicht-generische Collection | ArrayList arr = new ArrayList(); | arr.Add(10); | Legacy, vermeiden in modernem C# |
Queue<T>.Contains() | Element überprüfen | q.Contains(10); | bool vorhanden = q.Contains(5) | O(n) |
Stack<T>.Contains() | Element überprüfen | s.Contains(10); | bool vorhanden = s.Contains(5) | O(n) |
HashSet<T>.UnionWith() | Vereinigung | hs1.UnionWith(hs2); | hs1.UnionWith(hs2) | Mutativ |
HashSet<T>.IntersectWith() | Schnittmenge | hs1.IntersectWith(hs2); | hs1.IntersectWith(hs2) | Mutativ |
HashSet<T>.ExceptWith() | Differenz | hs1.ExceptWith(hs2); | hs1.ExceptWith(hs2) | Mutativ |
HashSet<T>.SymmetricExceptWith() | Symmetrische Differenz | hs1.SymmetricExceptWith(hs2); | hs1.SymmetricExceptWith(hs2) | Mutativ |
Dictionary\<TKey,TValue>.ContainsKey() | Schlüssel prüfen | dict.ContainsKey(1); | bool vorhanden = dict.ContainsKey(2) | O(1) |
Dictionary\<TKey,TValue>.ContainsValue() | Wert prüfen | dict.ContainsValue("Alice"); | bool vorhanden = dict.ContainsValue("Bob") | O(n) |
Queue<T>.TryPeek() | Sicheres Lesen | q.TryPeek(out int val); | bool ok = q.TryPeek(out val) | Vermeidet Exceptions |
Stack<T>.TryPeek() | Sicheres Lesen | s.TryPeek(out int val); | bool ok = s.TryPeek(out val) | Vermeidet Exceptions |
Stack<T>.TryPop() | Sicheres Entfernen | s.TryPop(out int val); | bool ok = s.TryPop(out val) | Vermeidet Exceptions |
Queue<T>.TryDequeue() | Sicheres Entfernen | q.TryDequeue(out int val); | bool ok = q.TryDequeue(out val) | Vermeidet Exceptions |
List<T>.Insert() | Einfügen an Index | zahlen.Insert(1, 99); | zahlen.Insert(0,10) | Elemente verschieben |
List<T>.RemoveAt() | Entfernen an Index | zahlen.RemoveAt(1); | zahlen.RemoveAt(0) | Elemente verschieben |
Dictionary\<TKey,TValue>.Count | Anzahl Paare | dict.Count | int total = dict.Count | Nur-Lesezugriff |
HashSet<T>.Count | Anzahl eindeutiger Elemente | hs.Count | int total = hs.Count | Nur-Lesezugriff |
Queue<T>.Count | Anzahl Elemente | q.Count | int total = q.Count | Nur-Lesezugriff |
Stack<T>.Count | Anzahl Elemente | s.Count | int total = s.Count | Nur-Lesezugriff |
SortedList\<TKey,TValue>.Count | Anzahl Elemente | sl.Count | int total = sl.Count | Nur-Lesezugriff |
LinkedList<T>.Count | Anzahl Elemente | ll.Count | int total = ll.Count | Nur-Lesezugriff |
ObservableCollection<T>.Count | Anzahl Elemente | oc.Count | int total = oc.Count | Nur-Lesezugriff |
ConcurrentDictionary\<TKey,TValue>.Count | Anzahl Elemente | cd.Count | int total = cd.Count | Nur-Lesezugriff |
ConcurrentQueue<T>.Count | Anzahl Elemente | cq.Count | int total = cq.Count | Nur-Lesezugriff |
ConcurrentStack<T>.Count | Anzahl Elemente | cs.Count | int total = cs.Count | Nur-Lesezugriff |
📊 Complete C# Properties Reference
Property | Values | Default | Description | C# Support |
---|---|---|---|---|
Count | int | 0 | Anzahl Elemente in der Collection | Alle Collections |
Capacity | int | 4 | Anzahl Elemente bevor Resize | List<T> |
IsReadOnly | bool | false | Nur-Lesezugriff? | ICollection<T>, IList<T> |
Keys | TKey Collection | N/A | Schlüsselsammlung eines Dictionary | Dictionary\<TKey,TValue> |
Values | TValue Collection | N/A | Wertekollektion eines Dictionary | Dictionary\<TKey,TValue> |
Comparer | IEqualityComparer | Default | Comparer für HashSet/Dictionary | HashSet<T>, Dictionary\<TKey,TValue> |
SyncRoot | object | null | Objekt zur Synchronisation | ICollection |
IsSynchronized | bool | false | Gibt Threadsicherheit an | ICollection |
CountChanged | Event | N/A | Event bei Änderung der Count-E |
🧠 Testen Sie Ihr Wissen
Test Your Knowledge
Test your understanding of this topic with practical questions.
📝 Anweisungen
- Lesen Sie jede Frage sorgfältig
- Wählen Sie die beste Antwort für jede Frage
- Sie können das Quiz so oft wiederholen, wie Sie möchten
- Ihr Fortschritt wird oben angezeigt