Objektvariable + Parameterübergabe mit ByVal und ByRef (Verständnisfrage)

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von picoflop.

    Objektvariable + Parameterübergabe mit ByVal und ByRef (Verständnisfrage)

    Hey,

    ich bin grad dabei das Entwicklerbuch Microsoft Visual Basic 2010 durchzuarbeiten und habe auch in der 2008er Version diesen Hinweis gefunden (2010-Seite 448, 2008-Seite 529):
    ByVal und ByRef haben für die Übergabe von Parametern, bei denen es sich um Referenztypen handelt, übrigens auch aus Auswirkungen ... beim Neuzuweisen von Objektvariablen.
    Wenn Sie eine Objektvariable, also eine Referenz, mit Byval übergeben und innerhalb dieser Prozedur der Objektvariablen eine neue Instanz zuweisen, dann ändert sich auch die Instanz, auf die die Objektvariable in der aufrufenden Prozedur zeigt. Mit ByRef ist das nicht der Fall.



    Ich dachte das ist genau anders rum, also mit ByVal wäre das nicht der Fall, so ist es auch in meinem Beispiel sofern ichs richtig gemacht hab:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Module Module1
    2. Sub Main()
    3. Dim haselnuss As pflanze
    4. haselnuss = New baum(150)
    5. Console.WriteLine("Die Pflanze ist so groß: " & haselnuss.Höhe.ToString & " - " & haselnuss.Art)
    6. Console.WriteLine("--- Funktionsaufruf ByVal---")
    7. val(haselnuss)
    8. Console.WriteLine("Die Pflanze ist so groß: " & haselnuss.Höhe.ToString & " - " & haselnuss.Art)
    9. Console.WriteLine("--- Funktionsaufruf ByRef---")
    10. ref(haselnuss)
    11. Console.WriteLine("Die Pflanze ist so groß: " & haselnuss.Höhe.ToString & " - " & haselnuss.Art)
    12. Console.ReadKey()
    13. End Sub
    14. Public Sub val(ByVal _pflanze As pflanze)
    15. _pflanze = New strauch(50)
    16. End Sub
    17. Public Sub ref(ByRef _pflanze As pflanze)
    18. _pflanze = New strauch(50)
    19. End Sub
    20. End Module
    21. Public MustInherit Class pflanze
    22. Public Property Höhe() As Integer
    23. Public Property Art() As String
    24. End Class
    25. Public Class baum
    26. Inherits pflanze
    27. Public Sub New(ByVal Pflanzenhöhe As Integer)
    28. Höhe = Pflanzenhöhe
    29. Art = "Baum"
    30. End Sub
    31. End Class
    32. Public Class strauch
    33. Inherits pflanze
    34. Public Sub New(ByVal Pflanzenhöhe As Integer)
    35. Höhe = Pflanzenhöhe
    36. Art = "Strauch"
    37. End Sub
    38. End Class


    Ergebnis:
    Die Pflanze ist so groß: 150 - Baum
    --- Funktionsaufruf ByVal---
    Die Pflanze ist so groß: 150 - Baum
    --- Funktionsaufruf ByRef---
    Die Pflanze ist so groß: 50 - Strauch


    Kann mir da jemand sagen wo mein Denkfehler liegt, oder ists doch im Buch falsch?
    Das passt schon, so wie du's hast.

    Mit ByVal wird der Inhalt der Variablen an die Sub übergeben und dort einer neuen Variablen (Instanz) zugeordnet.
    Deshalb ändert sich der Inhalt in der aufrufenden Prozedur nicht, sonder nur in der Sub.

    Mit ByRef wird der Pointer auf das Objekt übergeben, also keine neue Instanz davon angelegt.
    Änderungen in der Sub betreffen also die Variable (den Pointer) selbst und nicht deren Kopie, so dass die Veränderung auch ausserhalb der Sub wirksam sind.

    Edit: Tatsächlich - nach picoflops Post habe ich den Buchtext nochmals gelesen. Der ist wirklich falsch.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

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

    Das Verhalten ist völlig korrekt.
    ByVal - Übergabe als Value - als Wert, das Objekt als solches kann nicht ersetzt werden (wohl aber Eigenschaften innerhalb des Objekts).
    ByRef - Übergabe als Referenz - als Pointer (wenn Du das von C / C++ kennst), das Objekt als solches kann ersetzt werden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    also richtig ist:
    ByVal und ByRef haben für die Übergabe von Parametern, bei denen es sich um Referenztypen handelt, übrigens auch aus Auswirkungen ... beim Neuzuweisen von Objektvariablen.
    Wenn Sie eine Objektvariable, also eine Referenz, mit ByRef übergeben und innerhalb dieser Prozedur der Objektvariablen eine neue Instanz zuweisen, dann ändert sich auch die Instanz, auf die die Objektvariable in der aufrufenden Prozedur zeigt. Mit Byval ist das nicht der Fall.