Unterschied zwischen return und out

  • C#

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

    Unterschied zwischen return und out

    Hi Leute,
    könnt ihr mir mal den unterschied nennen zwischen den beiden möglichen Varianten erklären?

    Quellcode

    1. public void DoSomething()
    2. {
    3. int i = 4;
    4. return i;
    5. }

    Quellcode

    1. public void DoSomething(out int i)
    2. {
    3. int i = 4;
    4. }

    ich hab es zwar shcon benutzt, um noch ein paar extra daten aus einer Funktion heraus zu bekommen,
    mich interessiert aber der grundlegende unterschied zwischen den beiden, da man ja eigentlich return benutzen sollte um werte zurück zu geben.
    Die 1. Variante ist erst mal syntaktisch falsch, das ist eine Funktion, kein void:

    C-Quellcode

    1. public int DoSomething()
    2. {
    3. int i = 4;
    4. return i;
    5. }
    In der 2. Variante wird eine Variable by Reference übergeben, die nicht initialisiert zu sein braucht, die Prozedur befüllt sie, ebenfalls syntaktisch falsch, doppelte Deklaration von i:

    C-Quellcode

    1. public void DoSomething(out int i)
    2. {
    3. i = 4;
    4. }

    -----
    Meinst Du ggf. den Unterschied von

    Quellcode

    1. public void DoSomething(out int i)
    2. // zu
    3. public void DoSomething(ref int i)
    ?
    Hier ist der Unterschied in der Verwendung des Parameters im Aufruf sowie in der Verwendung.
    Beide können den Inhalt von i ändern, bei Aufruf mit ref muss die Variable initialisiert sein, mit out nicht.
    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!
    Bei nur einer Variable macht der Referenzaufruf keinen Sinn, aber manchmal möchte man nicht nur eine Variable zurückgeben sondern 2 oder mehrere, das geht nicht mehr mit Return, weil da kann man ja nur ein Wert angeben, mittels Referenz kannst du die übergebenen Variablen ändern.

    Quellcode

    1. public void do(out int i, out int x, out int y) {
    2. i = 5;
    3. x = 42;
    4. y = 32;
    5. }
    Ist wie ByRef / Return in VB.NET.

    VB.NET-Quellcode

    1. Dim i As Integer
    2. Sub Main()
    3. Something(i)
    4. 'Jetzt hat i den Wert 4.
    5. Msgbox(i)
    6. End Sub
    7. Sub Something(ByRef i as integer)
    8. i = 4
    9. End Sub

    VB.NET-Quellcode

    1. Sub Main()
    2. msgbox(Something()) 'Der Funktionsaufruf hat jetzt sozusagen den Wert 4.
    3. End Sub
    4. Function Something() as integer
    5. return 4
    6. End Sub
    (aus dem Kopf)

    EaranMaleasi schrieb:

    also letztendlich stellt out einfach eine möglichkeit dar, weitere werte aus einer funktion auszugeben? man sollte aber bei einer einzigen ausgabe dennoch return benutzen?
    Ganz genau! :thumbsup:

    f# zB. unterstützt die Rückgabe mehrerer Werte, aber bei c# und vb.net behilft man sich am einfachsten mit solch Referenz-Argumenten.

    EaranMaleasi schrieb:

    return benutzen?
    Im Allgemeinen: Ja,
    im Speziellen: Je nach Kontext, wenn diese Variable immer als Parameter übergeben wird, sollte sie auch bei nur einem Parameter, diesem selbst, als Parameter übergeben 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!

    RodFromGermany schrieb:

    im Speziellen: Je nach Kontext
    also ich wüsste jetzt keinen Kontext, wo byRef/out zu bevorzugen wäre, wenn man das Ergebnis ebensogut als Return-Wert zurückgeben kann.

    Im Gegenteil: Beim Code-Lesen eines returnenden Aufrufes ist offensichtlich, dass ein Wert geändert wurde.
    Beim Byref-Parameter, insbesondere in VB.Net ist das ühaupt nicht ersichtlich, und daher für unerfreuliche Überraschungen total gut.

    Hier ist c# malwieder besser, dass die die ByRef-Übergabe auch beim Aufruf kenntlich machen (out/ref).
    Aber auch in c# würde ich das Feature vermeiden, wo möglich, denn eine ordentliche Rückgabe ist leserlicher.

    Wie gesagt: Wirklich gut ist hier f#, wo man einfach mehrere Werte gemeinsam zurückgeben kann:

    VB.NET-Quellcode

    1. Dim dic As Dictionary(Of String, Point)
    2. Dim (success, pt) = dic.TryGetValue("key1")
    Ich hoffe halt, dass das auch iwann in vb.net/c# kommt.
    Ich möchte nochmal ein typisches Anwendungsbeispiel für out nennen. Die TryaParse-Methoden. Beispielsweise wird bei int.TryParse true oder false zurück gegeben, je nachdem ob der übergebene String wirklich eine Zahl ist oder nicht. Um nun ggf. nicht nochmal parsen zu müssen, wird der wert im 2., übergebenen, Parameter gespeichert.
    Ich denke, das es in solchen Fällen Sinn macht out zu nutzen, ansonsten würde ich auch darauf verzichten ;)