Parameter ByVal oder ByRef übergeben

Ich will kurz erklären, wie ich auf diesen Blogeintrag gekommen bin: Wir haben vor kurzem unsere internen Namenskonventionen überarbeitet. In diesem Kontext kam die Frage auf, ob man lokale Variablen von Parametern anhand der Schreibweise unterscheiden können sollte. Das macht natürlich dann Sinn, wenn sich eine lokale Variable anders verhält als eine, die per Parameter in die Methode injiziert wurde. Wann ist das der Fall? Nun, hier gilt es zu unterscheiden, ob die Variable ByValue (in C# gibt man hier nichts an) oder ByRef (in C# verwendet man das Schlüsselwort ref) übergeben wird.

Wo liegen die Unterschiede:

Handelt es sich bei dem Parameter um einen Wertetyp, so muss man eine Unterscheidung machen, da sich die Variable unterschiedlich verhält. Hierzu verweise ich auf diesen Link, der besagt, dass bei Werttypen, die per Referenz als Parameter an eine Subroutine übergeben werden, Änderungen sich nicht auf die Subroutine beschränken, sondern sich auf die aufrufende Routine auswirken. Wird die Variable hingegen per ByVal übergeben, so haben Änderungen daran nur lokale Auswirkungen (d.h. im Kontext der Subroutine).

Anders sieht es bei Parametern aus, die einen Referenzdatentyp abbilden. Hier spielt es keine Rolle, wie der Parameter an die Subroutine übergeben wird. Da in beiden Fällen immer nur der Zeiger auf das Objekt übergeben wird, haben Änderungen immer globale Auswirkungen. Vergleicht dazu auch diesen Artikel hier (Kommentare beachten).

Als ich dazu etwas programmiert habe, bin ich aber noch auf folgende Entdeckung gestoßen, die mir doch Rätsel aufgibt:

    Sub Main()
        Dim i = 15
        Console.WriteLine(Object.ReferenceEquals(i, i))
        ReferenceTestWithValueTypes(i, i)
        Console.ReadLine()
    End Sub

    Public Sub ReferenceTestWithValueTypes _ (ByRef object1 As Int32, ByRef object2 As Int32)

        Console.WriteLine(Object.ReferenceEquals(object1, object2))
        object2 = 20
        Console.WriteLine(object1)
        Console.WriteLine(object2)
        Console.WriteLine(Object.ReferenceEquals(object1, object2))
    End Sub

Die Ausgabe produziert folgendes Ergebnis:

clip_image002

Vielleicht kann ein Leser dies auflösen?!

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: