Schlagwort-Archive: Collections

C#.NET : Custom Collections anstelle von List erstellen über die mit foreach( … ) iteriert werden kann

Intention

Um die Klasse List<T> vor Zugriffen zu schützen / zu beschränken oder diese mit Notification-Events (z.B. ObservableCollection) auszustatten werden für den jeweiligen Verwendungszweck eigene Collections verwendet.

Ansatz

Um eine eigene Collection zu erstellen, welche mit foreach( … ) über die Elemente der eingekapselten Struktur (also z.B. List<T>) zu iterieren, benötigt man eine Enumerator-Klasse, welche die Methoden …

  • MoveNext()
  • Reset()
  • … und die Property „Current“ implementiert

implementiert (hier MyCollectionEnumerator) … sowie natürlich die gecustomizte Collection-Klasse selber, die die Datenstruktur enthält (hier MyCollection).

Lösung

using System;
using System.Collections.Generic;

namespace Irrsinn
{
    // Diese Klasse definiert mit MoveNext / Reset und der Property
    // Current aus dem Interface IEnumerator wie foreach(String s in col)
    // über die eingekapselte Liste iterieren darf.
    public class MyCollectionEnumerator : System.Collections.IEnumerator
    {
        private List<string> StringList;
        private int Counter = -1;

        // Im Konstruktor wird die Liste übergeben um die Operationen
        // MoveNext / Reset / Current darauf ausführen zu können
        public MyCollectionEnumerator(List<string> _StringList)
        {
            this.StringList = _StringList;
        }

        // Geht auf den nächsten Datensatz, der in der Liste 
        // gespeichert ist. Wenn MoveNext() false zurückgibt
        // ist das Ende der Liste erreicht
        public bool MoveNext()
        {
            Counter++;
            return Counter < StringList.Count;
        }

        // Setzt die Collection zurück.
        public void Reset()
        {
            Console.WriteLine("RESET!");
            Counter = -1;
        }

        // Gibt immer das aktuelle Element zurück, was mit 
        // MoveNext erreicht wurde
        public object Current
        {
            get
            {
                return StringList[Counter];
            }
        }
    }

    public class MyCollection
    {
        // Intern ist sind Collections meistens vom Typ List<T>
        // aber die eigene Implementierung gibt uns die Möglichkeit
        // den Zugriff auf die Liste anzupassen.
        private List<string> _StringList = new List<string>();

        // Hinzufügen eines Strings
        public void AddString(string newString)
        {
            this._StringList.Add(newString);
        }

        // GetEnumerator wird benötigt um mit foreach(...)
        // über die Collection zu iterieren
        public System.Collections.IEnumerator GetEnumerator()
        {
            return new MyCollectionEnumerator(_StringList);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Gecustomizte Collection
            MyCollection myCol = new MyCollection();
            myCol.AddString("Schatzi schenk mir ein Foto");
            myCol.AddString("schenk mir ein Foto vom Bier");
            myCol.AddString("Schatzi schenk mir ein Foto");
            myCol.AddString("Dann schenk ich Dir auch eins");
            myCol.AddString("vom Tier (also von den Muppets)");


            foreach (string s in myCol)
            {
                Console.WriteLine(s);
            }

            Console.ReadLine();
        }
    }
}

C# .NET : Collections im .NET Framework

Intention

Eines der wichtigsten .NET Elemente zum Verwalten vom Datenbeständen im Speicher sind Collections (Auflistungen). Im Vergleich zu normalen Array-Typen bieten diese die Möglichkeit zur Laufzeit Objekte hinzuzufügen, ohne vorher die Größe/die Anzahl der Objekte in der Collection zu kennen. Collections bieten Funktionen zum Hinzufügen, Entfernen und Suchen/Finden von Objekten. Ist ein Objekt in einer Auflistung erstmal gefunden, kann dieses über die Objektreferenz auch direkt in der Auflistung geändert werden.

Typsicher
  • Bessere Leistung
  • keine explizite Umwandlung notwendig um auf Objekteigenschaften zuzugreifen
  • Akzeptieren beim Erstellen einen Typparamter <T>
  • Unterstützung für Windows-Store-Apps
Typsicher…
Generische Auflistungen
Generische Auflistun…
Nicht
generische Auflistungen
Nicht…
Auflistungen
(Collections)
Auflistungen…
Nicht typsicher
  • Speichern Elemente als Objekt (Object)
  • erfordern explizite Umwandlung in den Objekttyp um auf Objekteigenschaften zuzugreifen
  • keine Unterstützung für Windows-Store-Apps
Nicht typsicher…
System.Collections.Concurrent
System.Collections.Concurrent
System.Collections
System.Collections
System.Array
System.Array
System.Collections.Generic
System.Collections.Generic
Threadsicher
Threadsicher
Findet man oft in älterem Code
Findet man oft…
System.Collections.Immutable
System.Collections.Immutable
NuGet-Paket
NuGet-Paket
Actor
Actor
Hinzufügen
Hinzufügen
Ändern
Ändern
Entfernen
Entfernen
Suchen
Suchen
        Collection
  1. Object 1
  2. Object 2
  3. Object 3
  4. Object n
Collectio…
«interface»
 System.Collections.IEnumerable
«interface»…
foreach(Object o in Collection) 
{
  o.Property…
}
foreach(Object o in Collectio…
«interface»
 System.Collections.Generic.IEnumerable
«interface»…
LINQ
var
query = from Object o in Collection
where o.Attribute > 95
select o;

foreach (Object o in query) {
Console.WriteLine(o.Attribute + „“
);
}
LINQ…
Viewer does not support full SVG 1.1

Auflistungen implementieren das Interface „IEnumerable“, um das Iterieren durch die Objekte in der Liste zu ermöglichen. Die foreach-Schleife nutzt beispielsweise dieses Interface um durch alle Objekte einer Collection zu iterieren.

Über die Abfragesprache LINQ (Language Integrated Query) lassen sich SQL-ähnliche Abfragen auf Collections durchführen,

Namespaces / Namensräume

Der Namensraum für .NET Framework Collections liegt unter System.Collections.*, wobei weitere Sub-Namensräume existieren.

  • System.Collections.Concurrent (mehrere Threads / Tasks können parallel auf diesen Collections im Speicher operieren)
  • System.Collections.Immutable (man arbeitet hierbei nur auf Kopien / die ursprünglichen Daten werden nicht geändert – muss zusätzlich über NuGet-Paket installiert werden)
  • System.Collections.Generic

Dynamische Strukturen/Collections allokieren immer 2^n Speicher-Plätze

Die Property „Capacity“, welche an jeder Collection anhängt, zeigt die Anzahl der Speicherplätze, die die Collection intern als Array alloziert hat. Bei 1025 Elementen werden intern 2048 Plätze vorbereitet. Bei 2049 Elementen werden intern 4096 Plätze vorbereitet.