Tuple oder Class

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von BlueLagoonX.

    Tuple oder Class

    Moin,

    derzeit stelle ich mir die Frage, warum es überhaupt Tuples gibt.

    Hier mal ein Beispiel.

    VB.NET-Quellcode

    1. Private Sub Test()
    2. Dim Result As New Result With {.Message = "Test", .Code = 1, .IsError = False}
    3. Dim ResultTuple As New Tuple(Of Date, String, Integer, Boolean)(Date.Now, "Test", 1, False)
    4. End Sub
    5. Public Class Result
    6. Private Property FieldTimestamp As Date
    7. Public ReadOnly Property Timestamp As Date
    8. Get
    9. With Me
    10. Return .FieldTimestamp
    11. End With
    12. End Get
    13. End Property
    14. Public Property Message As String
    15. Public Property Code As Integer
    16. Public Property IsError As Boolean
    17. Sub New()
    18. With Me
    19. .FieldTimestamp = Date.Now
    20. End With
    21. End Sub
    22. End Class


    Die Vorteile beim Tuple sehe ich in der kürze, da man sich die die Klasse sparen kann.
    Allerdings gibt es so keine richtigen Feldbezeichnungen, oder doch?
    Ebenso gibt es keine extended Properties, welche gewisse Aufgaben wie z.B. das Eintragen des Datums in ReadOnly Feldern.

    Kommt das in etwa so hin, oder übersehe ich einen großen Vorteil eines Tuples im Vergleich zu einer Klasse?


    Grüße :)
    Ich fürchte du hast "Class" nicht verstanden.
    Ich zitiere mal MS-Docs zum Tuple
    ​Ein Tupel ist eine Datenstruktur, die über eine bestimmte Anzahl und eine bestimmte Sequenz von Elementen verfügt. Ein Beispiel für ein Tupel ist eine Datenstruktur mit drei Elementen (als 3-Tupel oder dreifach bezeichnet), die zum Speichern eines Bezeichners verwendet wird, z. b. der Name einer Person im ersten Element, ein Jahr im zweiten Element und das Einkommen der Person für dieses Jahr im dritten Element.
    Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.
    Doch doch, ich weiß schon was eine Klasse ist :)

    Wie im Beispiel verwende ich oft Klassen als Rückgabewert für Funktionen, was sich auch über ein Tuple lösen lässt.

    Mal ein etwas ausführlicheres Beispiel ...

    VB.NET-Quellcode

    1. Private Sub Test()
    2. 'Dim Result As New Result With {.Message = "Test", .Code = 1, .IsError = False}
    3. 'Dim ResultTuple As New Tuple(Of Date, String, Integer, Boolean)(Date.Now, "Test", 1, False)
    4. Dim Result = MachWas()
    5. Dim ResultTuple = MachWasTuple()
    6. With Result
    7. MessageBox.Show("Timestamp: " & .Timestamp & " | " & "Message: " & .Message & " | " & "Code: " & .Code & " | " & "IsError: " & .IsError & " | ")
    8. End With
    9. With ResultTuple
    10. MessageBox.Show("Timestamp: " & .Item1 & " | " & "Message: " & .Item2 & " | " & "Code: " & .Item3 & " | " & "IsError: " & .Item4 & " | ")
    11. End With
    12. End Sub
    13. Private Function MachWas() As Result
    14. 'DoStuff
    15. Return New Result With {.Message = "Test", .Code = 1, .IsError = False}
    16. End Function
    17. Private Function MachWasTuple() As Tuple(Of Date, String, Integer, Boolean)
    18. 'DoStuff
    19. Return New Tuple(Of Date, String, Integer, Boolean)(Date.Now, "Test", 1, False)
    20. End Function


    Die Eigenschaften des Rückgabeobjektes von MachWas und MachWasTuple sind in der Ausgabe identisch, bis auf die Bezeichnung der Eigenschaften.
    Auch wenn's nebensächlich ist:

    VB.NET-Quellcode

    1. Private Function MachWasTuple() As Tuple(Of Date, String, Integer, Boolean)
    2. Return New Tuple(Of Date, String, Integer, Boolean)(Date.Now, "Test", 1, False)
    3. End Function

    geht in neueren Versionen auch mit

    VB.NET-Quellcode

    1. Private Function MachWasTuple() As (Prozessdatum As Date, Infotext As String, Kundenzahl As Integer, HeuteRegnetEs As Boolean)
    2. Return (Date.Now, "Test", 1, False)
    3. End Function

    Dann kann man nach dem Aufruf von MachWasTuple auch was mit den Namen machen:

    VB.NET-Quellcode

    1. Dim Result = MachWasTuple
    2. If Result.Prozessdatum = Date.Today Then

    Aber zum Thema zurück: Ich verwende selten Tupels, weil ich häufig mit langlebigen Objekten arbeite. Da Tupels aber Datenstrukturen sind, verhalten sie sich an manchen Punkten anders. Und das kommt mir häufig ungelegen. Z.B. gibt es in dem Sinne kein Nothing.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ich bleibe bei meiner Aussage über die Klassen
    Ansonsten wäre dein MachWas() eine Methode deiner Klasse und deine Daten wären Properties der Klasse.

    Nachtrag: Bei Klassen wäre auch noch die Vererbung zu kennen
    Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „MrTrebron“ ()

    MrTrebron schrieb:

    Ansonsten wäre dein MachWas() eine Methode deiner Klasse
    Wat? Nur weil eine Klassenobjektinstanz außerhalb der Klasse selber erzeugt wird, bleibst Du bei welcher Aussage? Dass der Class nicht verstanden hat? :huh: Ich erzeuge dauernd Klasseninstanzen außerhalb der Klasse:

    VB.NET-Quellcode

    1. Using Dialog As New SubForm
    2. Dialog.ShowDialog(Me)
    3. End Using
    Und jetzt erzählt mir hier keiner, dass er in solch einem Fall konsequent meinen Post zum Thema anwendet.

    MrTrebron schrieb:

    und deine Daten wären Properties der Klasse
    Sind sie doch, siehe Post#1.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    Mir geht es darum, dass er (anscheinend) Klassen nur als Rückgabewert von Methoden sieht.
    Damit hat er aus meiner Sicht Klassen nicht verstanden.

    Sorry, dass ich jetzt vom Parkplatz aus keine Abhandlung über Klassen geschrieben habe.

    Hatte aber Zwischenzeitlich meinen Post auch noch editiert, aber natürlich keine vollständige Aufzählung.

    Nachtrag: nein das war auch nicht der einzige Punkt warum ich am Verstanden haben zweifele. Vielleicht in meinem Vorpost falsch rübergekommen.

    Ich hatte weiter oben eine Beschreibung der Tuple von MS zitiert. Wenn man nun weiß was eine Klasse ist, erkennt man die Abgrenzung.
    Diese wurde nicht erkannt und ja, ich bin dann nur auf das Beispiel eingegangen. Eben weil für mich gelesen Klassen nur als Ausgabeparameter erstellt werden.
    Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „MrTrebron“ ()

    Ah, ok. Danke für die Klarstellung/Präzisierung. Da habe ich bei Deinem Post auch einiges falsch verstanden.
    Auch wenn ich @BlueLagoonXs Kenntnisse nicht im Detail kenne, vermute ich trotzdem stark, dass er erstmal nur die Ähnlichkeit einer möglichen Tupel-/Klasseninstanzerzeugung ging. Dass es bei Klassen noch einige andere Varianten gibt, weiß er sicherlich. Es geht hier wohl nur eher um den direkten Vergleich in quasi ähnlicher Situation.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    BlueLagoonX schrieb:

    Die Vorteile beim Tuple sehe ich in der kürze, da man sich die die Klasse sparen kann.
    Allerdings gibt es so keine richtigen Feldbezeichnungen, oder doch?
    Jo, ich finde, das ist so das wesentliche.
    Also manchmal ganz nützlich für Kleinkram.
    Aber wirklich nur Kleinkram, wo man problemlos die Übersicht behält, trotz der nichtssagenden PropertyNames.

    Ebenfalls für Kleinkram interessant sind anonyme Typen. Die haben das mit den Namen schön gelöst, aber man kann einen anonymen Typ nicht an eine andere Methode weiterreichen - dassis auch wieder eine krasse Beschränkung.

    Neuerdings gibts ValueTuple - Strukturen. Die haben beide Probleme gelöst, und noch paar weitere Schnuckligkeiten.
    Aber sind eben auch nur generische Tuples: "Dumme" DatenContainer ohne interne Logik.
    Ich nehm Tuples manchmal wenn ich aus einer Methode mehrere Werte zurück geben will, es aber zu viel ist bzw. die Werte zu „unwichtig“ sind um eine Klasse zu erstellen.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @MrTrebron Ich arbeite ausschließlich Objektorientiert mit Klassen, nicht nur für Rückgabewerte. Mir ging es nur in diesem Beispiel nur um den Rückgabewert einer Funktion.

    Ein anderes runtergebrochenes Beispiel wäre ...

    VB.NET-Quellcode

    1. Private Function MachNochWas() As Tuple(Of Integer, Date)
    2. With Me
    3. Dim InsertedID As Integer = 0
    4. Using Sqlcommand As New MySql.Data.MySqlClient.MySqlCommand("...", .Connection)
    5. With Sqlcommand
    6. '...
    7. InsertedID = CType(.ExecuteScalar(), Integer)
    8. '...
    9. End With
    10. End Using
    11. Return New Tuple(Of Integer, Date)(InsertedID, Date.Now)
    12. End With
    13. End Function


    Das wäre eine Funktion innerhalb einer Klasse, die einen Datensatz in eine Datenbank einträgt, die ID und das Insert Datum des Datensatzes zurückgibt.
    Jetzt gibt es für den Rückgabewert für mich die Frage, mache ich für den Rückgabewert eine neue Klasse oder gebe ich ihn als Tuple zurück.
    Ich will damit keine aufwändigen Konstrukte bauen, Tuples als Klassenersatz verwenden oder sonstigen Mumpitz.

    @VaporiZed exakt, mir ging es in diesem Beispiel nur um die Möglichkeit, sich für einen Rückgabewert einer Funktion eine extra Klasse zu sparen.
    Dein Beispiel will mir auch nicht so ganz klar werden.

    Wenn es eine private Methode innerhalb der Klasse ist, was würdest du nun mit den zurückgegeben Werten machen?
    Wenn die an eine Property gehen, warum dann der Umweg über das Tuple?

    VB.NET-Quellcode

    1. Class ....
    2. ' Properties ....
    3. public SQLId As Integer
    4. public SQLInsertedTime As DateTime
    5. Private Function MachNochWas() As Tuple(Of Integer, Date)
    6. With Me
    7. Dim InsertedID As Integer = 0
    8. Using Sqlcommand As New MySql.Data.MySqlClient.MySqlCommand("...", .Connection)
    9. With Sqlcommand
    10. '...
    11. InsertedID = CType(.ExecuteScalar(), Integer)
    12. '...
    13. End With
    14. End Using
    15. SQLId = InsertedID
    16. SQLInsertedTime = Date.Now
    17. End With
    18. End Function

    (Einfach so aus dem Kopf geschrieben)
    Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.
    Wie @mrMo schrieb: Wenn Du quasi einfach mehrere Rückgabewerte aus einer Funktion brauchst, nimm Tupels. Wenn Du hingegen ein Objekt erzeugst und mit dem weiterarbeiten willst, weil Du es im Gesamten z.B. einer List(Of T) hinzufügen willst, "nimm Class".
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo @BlueLagoonX

    Ich denke es ist alles schon gesagt worden, was man wissen muss. Ich möchte dir hier gerne ein paar wesentliche Vorteile einer Klasse näher bringen.

    Tuples verwende ich auch nur, wenn es klar ist, was zurückgegeben wird, und diese auch nicht gross weiter verarbeitet werden müssen.

    Werden aber die entsprechenden Werte noch weiter verarbeitet, oder müssen durch mehrere Methoden geschleust werden, bis sie zum gewünschten Adressat für die Verwendung sind, dann hat natürlich ein Klassentype nur Vorteile, denn dass "Rummreichen" eines Klassentypes braucht nur eine Referenz mehr nicht. Auch ist es möglich in der Klasse die Felder oder Members mit einer klaren Benennung zu versehen, und man weiss sofort, um was es sich handelt. Anderseits können im entsprechenden Klassentype noch Methoden eingebaut werden, die es erlauben, die entsprechenden Werte erst "Vorort", also am gewünschten Ort der Nutzung, für das was es gebraucht wird umzurechnen oder zu konvertieren.

    Beim "Durchreichen" der Werte durch die Methoden darf der Klassentype als Vorteil gesehen werden, denn bei jeder Methode wird in der Parameterliste nur die Referenz kopiert. Der dahinterliegende Speicherbereich bleibt unberührt. Beim Tuple hingegen werden Referenz wie auch die vorhandenen Werte neu kopiert, da das Grundprinzip einer Tuple auf der Struktur basiert.

    Kurz gesagt, um so mehr Werte zusammengehalten werden müssen, und um so mehr die Umsetzung der Nutzung der Werte komplexer werden, um so mehr Vorteile bietet hier ein eigener Klassentype. Klassen können auch in Klassen geschrieben werden mit dem Zugriffs-Modifizierer "Private", so das sie nach aussen nicht sichtbar sind, aber intern für die Klasse vollumfänglich nutzbar sind.

    Freundliche Grüsse

    exc-jdbi
    Miniaturanmerkung:

    exc-jdbi schrieb:

    Auch ist es möglich in der Klasse die Felder oder Members mit einer klaren Benennung zu versehen
    Was - wie ich weiter oben erwähnt habe - auch bei Tupels geht.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @MrTrebron Private war in dem Falle falsch, es hätte Public sein sollen.

    Es geht mir einfach nur um eine simple Rückgabe einer Funktion, oder die Zwischenspeicherung innerhalb einer Sub/Function, von mehreren verschiedenen Werten.
    Diese Rückgabe dient ausschließlich der Rückgabe von Informationen an den Aufrufer der Funktion.
    Wird mit der Rückgabe noch mehr gemacht, verwende ich immer Klassen.

    Meine Frage war einfach nur sehr allgemein gehalten, ob es praktikabel ist, Tuples statt Klassen als einfache Rückgabe für Funktionen zu verwenden, mehr nicht.

    Ich freue mich aber, dass die abschließende Meinung mit meiner Einschätzung übereinstimmt.