Verwirrung ByRef, ByVal

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Nixsager.

    Verwirrung ByRef, ByVal

    Hey,

    nun ich bin jetzt bei meinem letzten Kapitel in meinem EInsteigerbuch (noch 25 Seiten) ^^

    Wollte aber nochmal zurückgreifen auf ByVal und ByRef, was mich ziemlich verwirrt.. =/

    ByVal = Veränderung der Werte in der Prozedur/Funktion aber nicht außerhalb.

    ByRef = Veränderung der Werte außerhalb & Funktion/Prozedur.

    Und siehe:

    VB.NET-Quellcode

    1. Module Module1
    2. Sub Test(ByVal txt As String, _
    3. ByRef Netto As Decimal, _
    4. ByRef Preis As Decimal)
    5. txt = "Neuer Text"
    6. Netto = 15.0
    7. Preis = 16.0
    8. End Sub
    9. Sub Main()
    10. Dim Text As String = "Alter Text"
    11. Dim Wert1 As Decimal = 0.0
    12. Dim Wert2 As Decimal = 0.0
    13. Console.WriteLine(Text & " " & _
    14. Wert1.ToString() & " " & _
    15. Wert2.ToString())
    16. Test(Text, Wert1, Wert2)
    17. Console.WriteLine(Text & " " & _
    18. Wert1.ToString() & " " & _
    19. Wert2.ToString())
    20. Console.ReadLine()
    21. End Sub
    22. End Module



    =

    Alter Text 0 0
    Alter Text 15 16


    Wenn ich das jetzt richtig verstanden habe, hat der ByVal txt Wert sich nur innerhalb der Prozedur geändert aber nicht außerhalb und der Wert , Wert1, Wert2 hat sich wegen ByRef von 0, 0 in 15 und 16 geändert -> also außerhalb.

    Richtig?

    Aber wo wendet man denn ByVal und ByRef in nützlichen Programmen an?
    byval würde ich mal als Standart ansehen.
    byref verwendet man zB wenn man 2 Ergebnisse aus einer sub herausholen will:

    VB.NET-Quellcode

    1. private sub Irgendwas(byref param1 as integer, byref param2 as integer)
    2. param1 = 2*param2
    3. param2 = 1 +param1
    4. end sub
    5. 'aufruf:
    6. dim a,b as integer
    7. a=1
    8. b=2
    9. Irgendwas(a,b)
    10. msgbox a & "/" & b
    11. 'ergibt: 4/2
    Für ein Mindestmaß an Rechtschreibung, Interpunktion und Majuskeln!
    Hi
    Also ByRef und ByVal dienen diesem Zweck:
    ByVal übergibt an eine Methode oder einen Konstruktor einen Wert. Dieser Wert kann dabei verändert werden, jedoch wird nicht der Ursprung geändert.
    ByRef übergibt an eine Methode eine Referenz. Wenn du also innerhalb der Methode einen neuen Wert setzt, wird das auch in der Quelle getan.

    VB.NET-Quellcode

    1. Public Sub X(ByRef value As String)
    2. value = "bla"
    3. End Sub
    4. Public Sub Y()
    5. Dim xValue As String = "123"
    6. X(xValue)
    7. MessageBox.Show(xValue)
    8. End Sub


    Die MessageBox, die in Y erzeugt wird, gibt an dieser Stelle "bla" aus, da in X value auf "bla" gesetzt wird.

    VB.NET-Quellcode

    1. Public Sub X(ByVal value As String)
    2. value = "bla"
    3. End Sub
    4. Public Sub Y()
    5. Dim xValue As String = "123"
    6. X(xValue)
    7. MessageBox.Show(xValue)
    8. End Sub


    Hier wird dann "123" ausgegeben.

    Du kannst aber trotzdem eine Veränderung an der Instanz einer Klasse, die du übergibst, vornehmen. Bei Wertetypen funktioniert dies nicht. (Also wenn du z.B. eine Instanz TestInstanz der Klasse Test mit einer Eigenschaft Blubb des Typs String erzeugst, kannst du auch bei ByVal TestInstanz.Blubb verändern).

    Verwendet wird das Ganze zum Verändern von Wertetypen oder bei einer Rückgabe mehrerer Werte, ohne eine eigene Klasse zu erzeugen.

    Gruß
    ~blaze~
    ByVal => By Value legt eine Kopie iener Variablen an, sofern es sich um einen einfachen Datentyp handelt, also String, Integer, Double aber KEIN Object.

    Würdest du an eine Methode z.B. über ByVal das Object einer Textbox übergibst, kannst du direkt auf die Textbox zugreifen.

    Aufruf:

    VB.NET-Quellcode

    1. Start(Me.Textbox1)


    Methode:

    VB.NET-Quellcode

    1. Private Sub Start(ByVal c As Textbox)
    2. c.Text = "Hallo Welt!"
    3. End Sub


    Obwohl das Contorl hier mit ByVal übergeben wurde, wird trotzdem keine Kopie angelegt.
    ByRef ist mittlerweile eingentlich nicht mehr notwendig weil es dafür Funktionen gibt die eben Objecs zurück geben können, wenn man mehrere Werte zurückgeben will.

    VB.NET-Quellcode

    1. Private Function MeineFunktion() As MeineKlasse
    2. End Function


    ByRef wird vemrehrt noch bei den WinAPIs verwendet, weil diese KEINE Objekte zurückgeben sondern nur Integers, Strings usw. Oftmals kommt es aber vor das die API mehrere Werte ausgeben soll und dann wird ByRef genutzt um auf vorher definierte Variablen zuzugreifen.
    Hi

    Ich schreibe gerade was unter VBDOS und habe eine Problem mit den Variabeln.

    Ich habe es folgendermaßen verstanden.
    Wenn ich ein Funktion- oder Sub-Routine habe und ByRef nicht nutze (ist bei VBDOS standard) und ändere der Wert der Variabel so wird der Wert außerhalb der Routine übergeben.

    Mal ein Beispiel von mir.

    Folgenden Code nutze ich für das Schreiben einer Variabel und zum aufrufen der Routine.

    VB.NET-Quellcode

    1. DIM TempText as STRING
    2. TempText = "Hallo"
    3. TextOut TempText


    Das ist die Routine dir mir Probleme macht.

    VB.NET-Quellcode

    1. SUB TextOut (Text as STRING)
    2. Text = Text + "Zusatz"
    3. PRINT Text
    4. END SUB


    Wenn ich dir Routine mehrmals hintereinander aufrufe, bekomme ich folgendes Ergebnis:
    HalloZusatz
    HalloZusatzZusatz
    HalloZusatzZusatzZusatz
    HalloZusatzZusatzZusatzZusatz
    HalloZusatzZusatzZusatzZusatzZusatz
    usw.

    Was vermute jetzt, das die Variabel 'Text' global auch außerhalb der Routine genutzt wird.
    Und wenn ich ByVal vor der Variabel setze, wird die Variabel nur noch in der Routine genutzt und der Wert in der Routine wird nicht zurückgeschrieben.

    Liege ich damit richtig oder falsch???
    Deine Schlußfolgerung klingt sehr plausibel, aber:

    Was vermute jetzt, das die Variabel 'Text' global auch außerhalb der Routine genutzt wird.

    Die Variable Text wird nicht ausserhalb genutzt, sondern der Wert von Text aus der Sub wird mit ByRef an die Variable TextText zurückgegeben.

    Quellcode

    1. ByRef [Übergabe By Reference - Übergabe als Referenz]
    2. ByVal [Übergabe By Value - Übergabe als Wert]


    Aus deinen Post ist nicht ersichtlich, was eigentlich das Problem darstellt.
    Nicht ersichtlich???
    Ich dachte ich hätte alles ausführlich beschrieben? ?(

    der_Kurt schrieb:

    Deine Schlußfolgerung klingt sehr plausibel, aber:

    Die Variable Text wird nicht ausserhalb genutzt, sondern der Wert von Text aus der Sub wird mit ByRef an die Variable TextText zurückgegeben.

    Das 'TextText' ist woh ein Tippfehler?

    Aber tortzdem verstehe ich dein Aussage nicht. ?(
    Ist doch Jacke wie Hose.
    Nur das ich die Variabel Text nicht an eine andere Routine übergebe.
    ?(
    Mit ByRef gibst du den Wert aber wieder zurück, im Gegensatz zu ByVal.

    Wenn du schon siehst, dass ich (ausser "liege ich richtig oder falsch") keine konkrete Frage finde, auf die ich antworten kann,
    dann sind Jacke und Hose und die vielen Smileys nicht gerade hilfreich.

    PS: Yeah, Texttext war ein Tippfehler.