61 Stimmen

Wann sollte ich unsere Parameter verwenden?

Ich verstehe nicht, wenn eine Ausgabe-Parameter verwendet werden sollte, ich persönlich wickeln das Ergebnis in einen neuen Typ, wenn ich mehr als einen Typ zurückgeben müssen, ich finde, dass viel einfacher, mit als out zu arbeiten.

Ich habe solche Methoden gesehen,

   public void Do(int arg1, int arg2, out int result)

Gibt es Fälle, in denen das tatsächlich sinnvoll ist?

wie wäre es mit TryParse warum nicht eine ParseResult Typ? oder im neueren Framework einen nullbaren Typ zurückgeben?

33voto

jasonh Punkte 27971

Raus ist gut, wenn man eine TryNNN Funktion und es ist klar, dass der Out-Parameter immer gesetzt wird, auch wenn die Funktion nicht erfolgreich ist. Auf diese Weise können Sie sich darauf verlassen, dass die deklarierte lokale Variable gesetzt wird, und müssen nicht später in Ihrem Code auf Null prüfen. (Ein Kommentar weiter unten weist darauf hin, dass der Parameter auch auf null Sie sollten also die Dokumentation der Funktion, die Sie aufrufen, überprüfen, um sicherzugehen, dass dies der Fall ist oder nicht). Dadurch wird der Code ein wenig klarer und leichter zu lesen. Ein anderer Fall ist, wenn Sie einige Daten und einen Status über die Bedingung der Methode zurückgeben müssen:

public bool DoSomething(int arg1, out string result);

In diesem Fall kann die Rückgabe angeben, ob die Funktion erfolgreich war, und das Ergebnis wird im Parameter out gespeichert. Zugegeben, dieses Beispiel ist etwas konstruiert, denn man kann auch einen Weg finden, bei dem die Funktion einfach ein string aber Sie verstehen, was ich meine.

Ein Nachteil ist, dass Sie eine lokale Variable deklarieren müssen, um sie zu verwenden:

string result;
if (DoSomething(5, out result))
    UpdateWithResult(result);

Anstelle von:

UpdateWithResult(DoSomething(5));

Aber das ist vielleicht nicht einmal ein Nachteil, es kommt auf das Design an, das Sie anstreben. Im Fall von DateTime werden beide Möglichkeiten (Parse und TryParse) angeboten.

6voto

Gishu Punkte 130442

Nun, wie bei den meisten Dingen kommt es darauf an. Schauen wir uns die Optionen an

  • Sie können als Rückgabewert der Funktion zurückgeben, was Sie wollen
  • Wenn Sie mehrere Werte zurückgeben möchten oder die Funktion bereits einen Rückgabewert hat, können Sie entweder out params verwenden oder einen neuen zusammengesetzten Typ erstellen, der alle diese Werte als Eigenschaften bereitstellt

Im Fall von TryParse ist die Verwendung eines out-Parameters effizient - man muss keinen neuen Typ erstellen, was 16B Overhead bedeuten würde (auf 32b-Maschinen), oder die Kosten für das Garbage Collecting nach dem Aufruf in Kauf nehmen. TryParse könnte z.B. innerhalb einer Schleife aufgerufen werden - daher sind hier Out-Params die Regel.
Für Funktionen, die nicht innerhalb einer Schleife aufgerufen werden (d.h. die Leistung ist nicht von großer Bedeutung), könnte die Rückgabe eines einzelnen zusammengesetzten Objekts "sauberer" sein (subjektiv für den Betrachter). Jetzt mit anonymen Typen und Dynamic Typing könnte es noch einfacher werden.

Nota:

  1. out params haben einige Regeln, die befolgt werden müssen, d.h. der Compiler wird sicherstellen, dass die Funktion den Wert initialisiert, bevor sie beendet wird. TryParse muss also den out-Parameter auf einen Wert setzen, auch wenn der Parse-Vorgang fehlgeschlagen ist
  2. Das TryXXX-Muster ist ein gutes Beispiel dafür, wann man out params verwenden sollte - Int32.TryParse wurde eingeführt, weil sich die Leute über den Perf-Hit beim Abfangen von Exceptions beschwert haben, um zu wissen, ob das Parsen fehlgeschlagen ist. Außerdem ist das wahrscheinlichste, was Sie im Falle eines erfolgreichen Parsens tun würden, den geparsten Wert zu erhalten - die Verwendung eines Out-Params bedeutet, dass Sie keinen weiteren Methodenaufruf an Parse machen müssen

6voto

devuxer Punkte 40605

Ich denke, out ist nützlich für Situationen, in denen Sie sowohl einen Booleschen Wert als auch einen Wert zurückgeben müssen, wie TryParse, aber es wäre schön, wenn der Compiler so etwas erlauben würde:

bool isValid = int.TryParse("100", out int result = 0);

6voto

ThomasVestergaard Punkte 344

Ich weiß, ich komme mit meiner Antwort Jahre zu spät. out (und auch ref) ist auch sehr nützlich, wenn Sie nicht wollen, dass Ihre Methode ein neues Objekt instanziiert, um zurückzukehren. Dies ist sehr wichtig für Hochleistungssysteme, bei denen Sie eine Leistung unter einer Mikrosekunde für Ihre Methode erreichen wollen. Die Instanziierung ist aus der Sicht des Speicherzugriffs relativ teuer.

3voto

Christian C. Salvadó Punkte 763569

Out-Parameter sollten auf jeden Fall verwendet werden, wenn Sie eine Methode haben, die mehr als einen Wert zurückgeben muss, wie in dem von Ihnen genannten Beispiel:

public void Do(int arg1, int arg2, out int result)

Es macht nicht viel Sinn, einen out-Parameter zu verwenden, da Sie nur einen Wert zurückgeben, und diese Methode könnte besser verwendet werden, wenn Sie den out-Parameter entfernen und einen int-Rückgabewert setzen:

public int Do(int arg1, int arg2)

Es gibt einige gute Dinge über unsere Parameter:

  1. Die Ausgangsparameter werden zunächst als nicht zugewiesen betrachtet.
    • Jeder Ausgangsparameter muss definitiv zugewiesen werden, bevor die Methode zurückkehrt, Ihr Code wird nicht kompiliert, wenn Sie eine Zuweisung verpassen.

Zusammenfassend kann man sagen, dass ich grundsätzlich versuche, unsere Parameter in meinem private API um zu vermeiden, dass separate Typen erstellt werden, um mehrere Rückgabewerte zu verpacken, und in meiner öffentlichen API verwende ich sie nur für Methoden, die dem TryParse-Muster entsprechen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X