Fortgeschrittene Grundlagen: Referenzen und Verweise

Referenzen und Verweise werden in Funktionen dazu verwendet, einen Übergabeparameter innerhalb einer Funktion änderbar zu machen. Hierzu gilt zu sagen, dass alle Datentypen außer Objekte an die Funktion übergeben werden, so dass eine Änderung innerhalb der Funktion nicht die ursprüngliche Variable ändert. Da bei Objekten lediglich eine Referenz übergeben wird (da die eigentlichen Daten ja auf dem Heap liegen), wirken sich Änderungen am Übergabeparameter immer auf das ursprüngliche Objekt aus. Um eine solche Änderung der Parameter auch für die anderen Datentypen zu ermöglichen, gibt es die Referenzen und Verweise.
Für Referenzen und Verweise benötigen wir die Schlüsselwörter ref und out. Eines dieser Schlüsselwörter muss (falls gewünscht) bei der Funktions-Deklaration vor dem Datentyp angegeben werden. Des Weiteren muss das Schlüsselwort beim Funktionsaufruf vor dem Variablenname angegeben werden. Wir haben eine solche Referenz bereits bei den TryParse()-Funktionen für die Konvertierung einer Zeichenkette in eine Zahl verwendet. Referenzen und Verweise werden grundsätzlich gerne dazu verwendet, wenn eine Funktion mehrere Variablen ändern oder zurückgeben muss. Die TryParse()-Funktion ist hierbei das beste Beispiel: Wir wollen als Programmierer wissen, ob die Konvertierung erfolgreich war und wollen aber gleichzeitig den konvertierten Wert erhalten. Da eine Funktion jedoch immer nur einen Wert zurückgeben kann, wurde hier eine Referenz eingesetzt. Der Unterschied zwischen ref und out lässt sich wie folgt erklären: Wird eine Variable mit out übergeben, muss die Variable unbedingt in der Funktion initialisiert werden, d. h. die ursprüngliche Variable, darf vor dem Funktionsaufruf uninitialisiert sein. Eine Variable die mit ref übergeben wird, muss vor dem Funktionsaufruf initialisiert sein und muss nicht unbedingt in der Funktion zugewiesen werden.
Arrays und Objekte (und somit auch Listen) werden immer als Referenz übergeben, d. h. Änderungen an einem Wert in dem Array oder an einer Objekteigenschaft des Objektes wirken sich auf das Ursprungs-Objekt aus. Der Grund hierfür ist, dass Arrays und Objekte auf dem Heap gespeichert sind. Der Funktion wird also nicht das vollständige Array oder Objekt übergeben, sondern lediglich die Adresse auf dem Heap. Man spricht hierbei von reference passed by value. Wird das Array oder Objekt innerhalb der Funktion neu initialisiert / instanziiert, so wirken sich die Änderungen nicht auf das Ursprungs-Objekt aus (da hierdurch die Referenz-Adresse nur lokal geändert wird). Ist dieser Fall jedoch erwünscht (z. B. für die Initialisierung eines Objektes von einer anderen Funktion heraus) so benötigen wir das ref- bzw. out-Schlüsselwort.

Program.cs

using System;

namespace CSV20.Referenzen_Verweise
{
    class Program
    {
        static void Main(string[] args)
        {
            int iZahl = 17;
            int iZahl1 = 12;
            int iZahl2 = 54;
            int iMultiplikator = 3;
            int iErgebnis;              // unzugewiesene Variable

            Console.WriteLine("iZahl = " + iZahl);
            MultipliziereZahl(ref iZahl, iMultiplikator);
            Console.WriteLine("iZahl = " + iZahl);

            Console.WriteLine();

            Console.WriteLine("iErgebnis ist nicht zugewiesen");
            AddiereZahlen(iZahl1, iZahl2, out iErgebnis);
            Console.WriteLine("iErgebnis = " + iErgebnis);

            Console.ReadKey();
        }

        private static void MultipliziereZahl(ref int iZahl, int iMultiplikator)
        {
            Console.WriteLine("Multiplikation wird durchgeführt ...");
            // iZahl muss nicht zwangsläufig verändert werden
            iZahl = iZahl * iMultiplikator;
            // mathematische Operationen können auch abgekürzt werden
            //  > iZahl *= iMultiplikator;
        }

        private static void AddiereZahlen(int iZahl1, int iZahl2, out int iErgebnis)
        {
            Console.WriteLine("Addition wird durchgeführt ...");
            // iErgebnis muss immer zugewiesen werden, da die Variable 
            // andernfalls u. U. uninitialisiert wäre, was nicht passieren darf
            iErgebnis = iZahl1 + iZahl2;
        }
    }
}
Download

LinksRechts