Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 5 Min.

Mehr zu Tupeln

Die mit Visual Basic 15 eingeführten Tupel bündeln zusammengehörende Daten.
© dotnetpro
In der zurückliegenden Ausgabe der dotnetpro haben Sie die ersten Möglichkeiten des Programmierens mit Tupeln unter Visual Basic kennengelernt [1]. Wichtig: Sie benötigen dafür .NET ab Version 4.7 sowie Visual Studio 2017 oder 2019. Wichtigste Einschränkung: Tupel nehmen maximal acht Werte auf. Weiter geht’s jetzt mit der Option, Tupel in Listen zusammenzufassen.Mehrere Tupel mit gleichem Aufbau fassen Sie optional in Listen zusammen. Wie das geht, zeigt die Funktion GetAdressesList in Listing 1, die als Ergebnis eine Liste von Adress-Tupeln mit unbenannten Elementen zurückgibt. Dazu wird zunächst eine Liste angelegt, die dem Rückgabewert entspricht. Dieser Liste mit Namen tList werden dann drei Adress-Tupel hinzugefügt, um dann die Liste abschließend mit Return an das aufrufende Programm zu übergeben. Die folgenden Anweisungen zeigen den Aufruf der Funktion GetAdressesAsList, wobei der Zielvariablen tL der Datentyp durch die Funktion GetAdressesAsList übergeben wird.
Listing 1: GetAdressesAsList
Function GetAdressesAsList() As List(Of Tuple( 
  Of String, String, String, UInteger, UInteger,
  String)) 

  Dim tList As New List(Of Tuple(Of String, String,
    String, UInteger, UInteger, String)) 
  tList.Add(New Tuple(Of String, String, String, 
    UInteger, UInteger, String)("Peter", "Pan", 
    "Goethestraße", 234, 20323, "Hamburg")) 
  tList.Add(New Tuple(Of String, String, String,
    UInteger, UInteger, String)("Maria", "Müller", 
    "Schillerweg", 76, 80545, "München")) 
  tList.Add(New Tuple(Of String, String, String, 
    UInteger, UInteger, String)("Klaus", "Schmidt", 
    "Glockengasse", 7, 30567, "Hannover")) 

  Return tList 
End Function  

' Datenrückgabe als änderbare Werteliste 
Dim tL = GetAdressesAsList() 
Dim n as String = vbCrLf  ' Neue Zeile
Dim s as String = " "    ' Leerzeichen

MsgBox(
  "Anzahl Elemente: " & tL.Count & nZ &   "1. Element: " & tL(0).Item1 & s & tL(0).Item2 & n &   "2. Element: " & tL(1).Item1 & s & tL(1).Item2 & n &   "3. Element: " & tL(2).Item1 & s & tL(2).Item2, ...) 

Tupellisten nachträglich bearbeiten

Mithilfe der Methode Add der Tupelliste tL können Sie weitere Adresselemente hinzufügen. Alle Vor- und Nachnamen der erweiterten Liste werden per Meldung angezeigt (Bild 1).
Ausgabeder erweiterten Tupel-Adressliste(Bild 1) © Autor
' Liste erweitern 
tL.Add(New Tuple(Of String, String, String, 
  UInteger, UInteger, String)("Hans", "Friedrich", 
  "Bahnhoftstraße", 104, 60489, "Frankfurt")) 

MsgBox(
  "Anzahl Elemente: " & tL.Count & n &   "1. Element: " & tL(0).Item1 & s & tL(0).Item2 & n &   "2. Element: " & tL(1).Item1 & s & tL(1).Item2 & n &   "3. Element: " & tL(2).Item1 & s & tL(2).Item2 & n &   "4. Element: " & tL(3).Item1 & s & tL(3).Item2, ...) 
Mit RemoveAt entfernen Sie ein beliebiges Listenelement über den angegebenen Index – in Bild 2 wurde das Element mit dem Index 1 (Maria Müller) entfernt und das Ergebnis per Dialog angezeigt.
Die gekürzteTupel-Adressliste(Bild 2) © Autor
' Liste um einen Eintrag kürzen 
tL.RemoveAt(1) 
MsgBox( 
  "Anzahl Elemente: " & tL.Count & n & 
  "1. Element: " & tL(0).Item1 & s & tL(0).Item2 & n & 
  "2. Element: " & tL(1).Item1 & s & tL(1).Item2 & n & 
  "3. Element: " & tL(2).Item1 & s & tL(2).Item2, ... ) 
 
Mit einer For-Each-Anweisung iterieren Sie durch die Elemente einer Tupelliste. Im folgenden Beispiel werden die Tupel nacheinander verarbeitet und per Dialog angezeigt.

Dim Counter As Integer = -1 
For Each i As Tuple(Of String, String, String, UInteger, 
  UInteger, String) In tL
  With i 
  Counter += 1 
  MsgBox("Element: " & Counter & n & 
    "Vorname: " & i.Item1 & n & 
    "Nachname: " & i.Item2 & n & 
    "Straße: " & i.Item3 & n & 
    "Hausnummer: " & i.Item4 & n & 
    "PLZ: " & i.Item5 & n & "Ort: " & i.Item6, ...) 
 End With 
Next 
 
Bleibt anzuführen, dass auch Listen bereits diverse Methoden bieten (zum Beispiel Sort), die hier aber nicht im Detail behandelt werden sollen.

Tupel bearbeiten, klonen und ändern

Tupel lassen sich bearbeiten und können kopiert oder geklont werden (als Wertekopie/-klon). Um das bereits für Maria Müller eingerichtete Tupel mit benannten Elementnamen zu kopieren, legen Sie eine neue Variable an (hier MariaMüller2) und weisen dieser den Wert von MariaMüller zu. Mit Equals ist der unmittelbare Vergleich der Tupel möglich. Wie erwartet, werden beide Inhalte als gleich eingestuft.

Dim MariaMüller2 = MariaMüller 
If MariaMüller.Equals(MariaMüller2) Then 
  MsgBox("Die Tupel sind gleich!", ...) 
 
Wollen Sie Elemente eines Tupels bearbeiten, weisen Sie den jeweiligen Elementnamen neue Werte zu. Im folgenden Beispiel werden zum Tupel MariaMüller2 die Daten zu Postleitzahl und Wohnort geändert. Ein Vergleich zeigt, dass keine Gleichheit mehr mit dem kopierten Tupel MariaMüller besteht.

' Werteänderungen 
MariaMüller2.PLZ = 20323 
MariaMüller2.Ort = "Hamburg" 
If MariaMüller.Equals(MariaMüller2) Then 
  MsgBox("Die Tupel sind gleich!", ... )
Else 
  MsgBox("Die Tupel sind ungleich!", ...
End If 
 
Setzen Sie den Wert eines Tupels auf Nothing, so werden lediglich die Werte, nicht aber die Elementnamen und deren Datentypen entfernt. Die nachfolgende MsgBox-Anweisung ist zulässig, da der Wert weiterhin existiert und die Element­anzahl weiterhin gültig ist, nur die Werte sind auf Nothing gesetzt. Dementsprechend liefert der Dialog keinen Inhalt zum abgefragten Nachnamen zurück.

MariaMüller2 = Nothing 
MsgBox(MariaMüller2.Nachname) 
 
Eine Wertzuweisung wie MariaMüller2 = t2 funktioniert dementsprechend nicht, da sich die Struktur, die Datentypen und auch die Elementanzahl eines Tupels (hier MariaMüller2) im Nachhinein nicht mehr ändern lassen.
Iterierter Datensatzeiner Tupel-Adressliste(Bild 3) © Autor

Tupel mit unbenannten Funktionsergebnissen

An dieser Stelle soll gezeigt werden, wie Sie Funktionen definieren, die Tupel mit mehreren unbenannten Elementen als Ergebnis zurückliefern. Der Einfachheit halber wird erneut der Aufbau des Adress-Tupels genutzt. Die Funktion GetAdressAsTupel bekommt einen Indexwert übergeben, über den ein Adressdatensatz gewählt wird. Dieser wird als Tupel angelegt und per Return zurückgegeben (Listing 2).
Listing 2: GetAdressAsTupel
Function GetAdressAsTupel(
  ByVal Number) As (String, String, String, 
  UInteger, UInteger, String) 
  ' Rückgabe als Item1, Item2 usw... 
  Select Case Number 
    Case 1 
      Return ("Peter", "Pan", "Goethestraße", 234,
        20323, "Hamburg") 
    Case 2 
      Return ("Maria", "Müller", "Schillerweg", 76, 
        80545, "München") 
    Case 3 
      Return ("Klaus", "Schmidt", "Glockengasse", 7, 
        30567, "Hannover") 
    Case Else 
      Return Nothing 
  End Select 
End Function  
GetAdressAsTupel2 zeigt die entsprechende Definition auszugsweise, jetzt aber mit dem benannten Datentyp Value­Tuple und dem Of-Operator (Listing 3).
Listing 3: GetAdressAsTupel2 as ValueTuple
Function GetAdressAsTupel2(ByVal Number) As 
  ValueTuple(Of String, String, String, UInteger, 
  UInteger, String) 

  Select Case Number 
    Case 1 
      Return ("Peter", "Pan", "Goethestraße", 234,
        201323, "Hamburg") 
    Case 2 
    ...
    Case Else 
      Return Nothing 
  End Select 
End Function  
An dieser Stelle wird mit GetAdressAsTupel der Adressdatensatz mit dem Index 3 abgefragt und in die Variable MariaMüller2 übernommen. GetAdressAsTupel liefert unbenannte Elemente zurück und in MariaMüller2 sind entsprechend der ursprünglichen Kopie benannte Elementnamen angelegt. Dies erklärt, warum sich hier zur Werteausgabe im Meldungsdialog die benannten Elementnamen nutzen lassen.

MariaMüller2 = GetAdressAsTupel(3) 
' dies funktioniert nur, weil die Elementnamen 
' für MariaMüller2 weiterhing gültig sind 
MsgBox("MariaMüller2 – 
   Vorname: " & MariaMüller2.Vorname & n & 
  "Nachname: " & MariaMüller2.Nachname & n & 
  "Straße: " & MariaMüller2.Straße & n & 
  "Hausnummer: " & MariaMüller2.Hausnummer & n & 
  "PLZ: " & MariaMüller2.PLZ & n & 
  "Ort: " & MariaMüller2.Ort, ...) 
 
Richten Sie mit TestOhneElementNamen eine neue Variable ein und weisen Sie dieser das Ergebnis der Funktion GetAdressAsTupel2 zu, hier mit dem Indexwert 1, können Sie die Elementnamen für den Wertezugriff nicht verwenden, sondern müssen in jedem Fall die indizierten Item-Namen nutzen. Jede Änderung wird unmittelbar mit einer Fehlermeldung quittiert.
Die Prozedur ShowTupelAdress(Bild 4) © Autor

' neues Tupel, die Elementnamen sind nicht zugewiesen 
Dim TestOhneElementNamen = GetAdressAsTupel2(1) 
'dementsprechend ist eine Item-Angabe erforderlich 
MsgBox("MariaMüller2 - 
   Vorname: " & TestOhneElementNamen.Item1 & n & 
  "Nachname: " & TestOhneElementNamen.Item2 & n & 
  "Straße: " & TestOhneElementNamen.Item3 & n & 
  "Hausnummer: " & TestOhneElementNamen.Item4 & n & 
  "PLZ: " & TestOhneElementNamen.Item5 & n & 
  "Ort: " & TestOhneElementNamen.Item6, ... ) 

Tupel mit benannten Funktionsergebnissen

Selbstverständlich können Sie Funktionen auch so codieren, dass diese Tupel mit benannten Elementnamen zurückliefern, siehe Listing 4.
Listing 4: GetAdressNamedTupel
Function GetAdressAsNamedTupel(ByVal Number) As ( 
  Vorname As String, Nachname As String, 
  Straße As String, Hausnummer As UInteger, 
  PLZ As UInteger, Ort As String) 

  Select Case Number 
    Case 1 
      Return ("Peter", "Pan", "Goethestraße", 234,
        201323, "Hamburg") 
    Case 2 ...
    Case Else 
      Return Nothing 
  End Select 
End Function  
Definieren Sie nun eine neue Variable TestMitElement­Namen und weisen Sie dieser das Ergebnis der Funktion Get­AdressAsNamedTuple zu, so werden die Elementnamen wie gewünscht wieder in die Zielvariable übernommen. Sie können also wieder gezielt per Name auf Elemente zugreifen und diese im Dialog ausgeben.

Dim TestMitElementNamen = GetAdressAsNamedTupel(3) 
MsgBox("Klaus Schmidt - 
  Vorname: " & TestMitElementNamen.Vorname & n & 
  "Nachname: " & TestMitElementNamen.Item2 & n & 
  "Straße: " & TestMitElementNamen.Straße & n & 
  "Hausnummer: " & TestMitElementNamen.Item4 & n & 
  "PLZ: " & TestMitElementNamen.PLZ & n & 
  "Ort: " & TestMitElementNamen.Item6, ...) 
 
Die letztgenannte Wertzuweisung können Sie auch in der folgenden Langfassung vornehmen:

Dim TestAdresseMitElementNamen As (Vorname As String, 
  Nachname As String, Straße As String, 
  Hausnummer As UInteger, PLZ As UInteger, 
  Ort As String) = GetAdressAsNamedTupel(3) 

Tupel als Parameter

Bleibt zu zeigen, wie Sie Tupel an Funktionen oder Prozeduren übergeben. Die Funktion ShowTupelAdress übernimmt die Datenstruktur eines Adress-Tupels per Parameter und gibt diese aus.

Sub ShowTupelAdress(ByVal tAdresse As ( 
  String, String, String, UInteger, UInteger, String)) 

  'Typangabe erforderlich 
  Try 
    MsgBox(
      "Vorname: " & tAdresse.Item1 & n & 
      "Nachname: " & tAdresse.Item2 & n & 
      "Straße: " & tAdresse.Item3 & n & 
      "Hausnummer: " & tAdresse.Item4 & n & 
      "PLZ: " & tAdresse.Item5 & n & 
      "Ort: " & tAdresse.Item6, ... ) 
  Catch ex As Exception 
    MsgBox("Bei der Adressverarbeitung ist ein Fehler 
            aufgetreten!", ...) 
  End Try 
End Sub 
 
Das an die Prozedur übergebene Adress-Tupel muss diejenige Datenstruktur aufweisen, die auch in der Parameterliste definiert wurde. Dies ist bei der bereits definierten und initialisierten Variablen PeterPan sichergestellt.

ShowTupelAdress(PeterPan) 

Geschachtelte Tupel

Eine Sonderfunktion soll abschließend noch vorgestellt werden, das Verschachteln von Tupeln. Zwar lassen sich so die über ein einzelnes Tupel verwaltbaren Werte theoretisch auf 64 Elemente (8 mal 8) heraufsetzen, sinnvoll ist das aufgrund der Lesbarkeit aber nicht. Bei diesem Verfahren werden innerhalb eines Tupels bis zu acht untergeordnete Tupel definiert. Das folgende Beispiel erzeugt mit Tupel.Create nur ein untergeordnetes Tupel. Der Elementzugriff erfolgt elementbezogen:

Dim ntVar = Tuple.Create( 
  "erstes Wertepaar", Tuple.Create(23, 45)) 

MsgBox( 
  "Wert Haupttupel:    " & ntVar.Item1 & n & 
  "Untertupel 1. Wert: " & ntVar.Item2.Item1 & n & 
  "           2. Wert: " & ntVar.Item2.Item2, ... ) 
 
Anhand der Beispiele in dieser und der vorangegangenen Folge von Basic Instinct konnten Sie die kompakte Nutzung von Tupeln, die wichtigsten Einsatzmöglichkeiten, aber auch deren Schwachpunkte nachvollziehen. Prinzipiell machen Sie sich das Leben mit Tupeln einfacher, müssen dann aber auch in Kauf nehmen, dass die damit generierten Anwendungen zumindest .NET 4.7 erfordern. Lebensnotwenig sind Tupel generell nicht. Alles, was Sie mit Tupeln erreichen, realisieren Sie auch weiterhin – mitunter mit mehr Aufwand – auf den altbekannten Wegen.
Projektdateien herunterladen

Fussnoten

  1. Andreas Maslo, Werte mit Tupeln zusammenfassen, Teil 1, dotnetpro 6/2019, Seite 136 ff.,

Neueste Beiträge

Managed DevOps Pools - Azure DevOps Pipelines Security
Agent Pools als Managed Service mit einfacher Integration in private Netzwerke und Authentisierung mittels Managed Identity tragen deutlich zur Sicherheit der Agent-Infrastruktur bei.
7 Minuten
7. Aug 2025
Müssen Ziele SMART sein?
Wenn es um Ziele im Projektmanagement oder in der Führung einer Organisation geht, stoßen wir schnell und fast ausnahmslos auf das Akronym SMART. Was steckt dahinter, und kann es nicht auch sinnvolle Ziele geben, die nicht SMART sind?
8 Minuten
Arbeiten mit Tabellen und KI in Dataverse
Microsoft unterstützt die zentrale Datenmanagement-Lösung Dataverse in Power Apps mit KI-Features.
7 Minuten
6. Aug 2025
Miscellaneous

Das könnte Dich auch interessieren

Sicher ist sicher - Azure DevOps Pipelines Security
Als integraler Bestandteil der Entwicklungsumgebung ist Azure DevOps Pipelines oft Ziel von Angriffen. Da ist es gut zu wissen, wo die Schwachstellen des Systems liegen.
14 Minuten
16. Jun 2025
CodeProject.AI Server in neuer Version - Lokaler AI-Server
CodeProject.AI Server (jetzt in Version 2.1.10) ist ein lokal installierter, selbstgehosteter, schneller, kostenloser und Open Source Artificial Intelligence Server für jede Plattform und jede Sprache.
2 Minuten
Für Einsteiger: Backend-Webentwicklung mit .NET - Microsoft
Auf YouTube bietet Microsoft eine Videoserie für Einsteiger in die Backend-Webentwicklung mit .NET.
2 Minuten
13. Feb 2024
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige