Neu in .NET 8.0 [12]: Eingefrorene Objektmengen

.NET 8.0 bietet zwei neue Objektmengen, bei denen man nach dem Erstellen die Elemente nicht ändern, ergänzen oder löschen kann.

In Pocket speichern vorlesen Druckansicht 5 Kommentare lesen

(Bild: Rejdan/Shutterstock.com)

Lesezeit: 1 Min.
Von
  • Dr. Holger Schwichtenberg

.NET 8.0 bietet zwei neue Objektmengen FrozenSet<T> und FrozenDictionary<T, T> im neuen Namensraum System.Collections.Frozen. Bei diesen eingefrorenen Mengen kann man nach der Erstellung weder Elemente ändern, noch ergänzen oder löschen. Dafür liefern sie die enthaltenen Elemente schneller als andere verfügbare Objektmengen in .NET.

Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.

Eine eingefrorene Menge erstellt man mit zwei neuen Erweiterungsmethoden für die Schnittstelle IEnumerable<T>:

  • ToFrozenSet() gibt die Menge als Instanz von FrozenSet<T> zurück
  • ToFrozenDictionary() gibt die Menge als Instanz von FrozenDictionary<T, T> zurück.

Diese Methoden erstellen eine "eingefrorene" Liste bzw. ein Dictionary (mit Name-Wert-Paaren).

Es gibt drei Unterschiede zwischen der schon seit dem 2005 erschienen .NET Framework 2.0 verfügbaren ReadOnlyCollection<T> und dem nun in .NET 8.0 eingeführten FrozenSet<T>:

  • Implementierungen von ReadOnlyCollection<T> stellen nur die Sicht auf eine andere Menge dar, die man mit AsReadOnly() erzeugt. Hingegen ist FrozentSet<T> eine eigenständige Menge.
  • FrozenSet<T> besitzt keinen Indexer: frozenSet× funktioniert daher nicht.
  • FrozentSet<T> kann keine Duplikate enthalten, denn Sets erlauben keine Duplikate
Die Serie zu den Neuerungen in .NET 8.0

Folgender Code zeigt den Einsatz von FrozenSet im Vergleich zu anderen Objektmengen:

/// <summary>
 /// Klasse System.Collections.Frozen.FrozenSet: 
 /// Eine nur lesbare einfache Liste. 
 /// Duplikate warden automatisch entfernt!
 /// </summary>
 public void FrozenSet()
 {
  CUI.H2(nameof(FrozenSet));
 
  CUI.H3("FrozenSet aus Array");
  int[] Zahlen = new int[] { 1, 2, 3 };
  var f = Zahlen.ToFrozenSet();
  Console.WriteLine(f.GetType().FullName);
 
  CUI.H3("FrozenSet aus List");
  List<int> list = new List<int> { 42, 10, 50, 42 };
  FrozenSet<int> frozenSet = list.ToFrozenSet();
  Console.WriteLine(frozenSet.GetType().FullName);
  Console.WriteLine(frozenSet.Count); // nur 3, da keine Duplikate!
 
  #region -------------------  
  // Änderung -->  FrozenSet hat keinen Indexer, 
  // kein Add(), kein Remove()
  //frozenSet[2] = 10; // Ändern nicht möglich
  //frozenSet.Add(42); // Hinzufügen nicht möglich!!
  //frozenSet.Remove(42); // Hinzufügen nicht möglich!!
  #endregion
 
  CUI.H3("ReadOnlyCollection aus List"); 
  // gab es schon vor .NET 8.0 :-) --> 
  // ReadOnlyCollection<T> ist nur Sicht auf eine andere Menge, 
  // die man mit AsReadOnly() erzeugt.
  ReadOnlyCollection<int> readonlyList = list.AsReadOnly();
  Console.WriteLine(readonlyList.GetType().FullName);
  //readonlyList[2] = 10; // Ändern nicht möglich
  //readonlyList.Add(42); // Hinzufügen nicht möglich!!
 
  CUI.H3("ImmutableList aus List"); // gab es schon vor .NET 8.0 :-)
  ImmutableList<int> immutableList = list.ToImmutableList();
  Console.WriteLine(immutableList.GetType().FullName);
  //immutableList[2] = 10; // Ändern nicht möglich
  var newImmutableList = immutableList.Add(42);
  // Hinzufügen IST möglich, aber man bekommt eine neue Liste!
 
  #region ------------------- Änderungen in Ursprungsliste
  CUI.H3("Ein Element ändern");
  list[2] += 1; // drittes Element der Ursprungsliste ändern
  Console.WriteLine(list[2]); // 51
  Console.WriteLine(readonlyList[2]); // 51
  Console.WriteLine(immutableList.ElementAt(2)); // ist immer noch 50!
  Console.WriteLine(frozenSet.ElementAt(2)); // ist immer noch 50!
  #endregion
 
  #region ------------------- Elemente hinzufügen in Ursprungsliste
  CUI.H3("Ein Element hinzufügen");
  list.Add(77); // Ein fünftes Element ergänzen
  Console.WriteLine($"List count: {list.Count}"); // == 5!
  // == 5 weil: ReadOnlyList ist eine Sicht auf List<T>!:
  Console.WriteLine($"ReadOnlyList count: {readonlyList.Count}"); 
  // == 4 weil vorheriger Zustand der Liste: 
  Console.WriteLine($"ImmutableList count: {immutableList.Count}");  
  // == 5 neue Liste: 
  Console.WriteLine($"new ImmutableList count: {newImmutableList.Count}");  
  // == 3 FrozenSET: vorheriger Zustand, keine Duplikate: 
  Console.WriteLine($"FrozenSet count: {frozenSet.Count}"); 
  #endregion
 }

Den Einsatz von FrozenDictionary zeigt folgender Codeausschnitt:

public void FrozenDic()
 {
  CUI.H2(nameof(FrozenDic));
  List<int> list = new List<int> { 42, 10, 50, 42 };
 
  CUI.H3("FrozenDictionary aus List");
  FrozenDictionary<int, string> frozenDic = 
    list.Distinct().ToFrozenDictionary(x => x, 
                                       x => "Zahl " + x.ToString());
  Console.WriteLine(frozenDic.Count); // 3
  // frozenDic[0] = 2;
  // frozenDic.TryAdd(0, "Zahl 0"); // "Not supported"
 
  Console.WriteLine(frozenDic.GetType().FullName);
 }
}

(rme)