Frage

Ich verstehe nicht, wenn ein Ausgabeparameter verwendet werden soll, habe ich persönlich das Ergebnis in einer neuen Art wickeln, wenn ich mehr als eine Art zurückbringen müssen, finde ich, dass viel einfacher als mit zur Arbeit.

ich gesehen Methode wie folgt habe,

   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 TryParse, warum nicht geben einen ParseResult Typ? oder im neueren Rahmen gibt einen Null-able Typen?

War es hilfreich?

Lösung

Out ist gut, wenn Sie eine TryNNN Funktion haben, und es ist klar, dass die Out-Parameter werden immer noch festgelegt werden, wenn die Funktion nicht erfolgreich ist. Auf diese Weise können Sie sich darauf verlassen, dass die lokale Variable erklären Sie wird vielmehr festgelegt werden, als wenn Kontrollen später im Code gegen null zu setzen. (A Kommentar unten zeigt, dass der Parameter eingestellt werden könnte, um null, so dass Sie die Dokumentation für die Funktion überprüfen, sollten Sie anrufen sicher sein, ob dies der Fall ist oder nicht.) Es macht den Code ein wenig klarer und einfacher lesen. Ein anderer Fall ist, wenn Sie einige Daten und einen Status über den Zustand des Verfahrens zurückkommen müssen wie:

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

In diesem Fall kann die Rückkehr an, ob die Funktion erfolgreich und das Ergebnis wird in den Out-Parametern gespeichert. Zugegeben, dieses Beispiel ist gekünstelt, weil Sie eine Art und Weise gestalten können, wo die Funktion einfach ein string zurückgibt, aber Sie bekommen die Idee.

Ein Nachteil ist, dass Sie eine lokale Variable zu deklarieren, haben sie zu benutzen:

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

Statt:

UpdateWithResult(DoSomething(5));

Sie jedoch, dass nicht einmal einen Nachteil sein kann, hängt es von dem Entwurf, den Sie für geht. Im Fall von Datum- und beiden Mittel (parsen und TryParse) vorgesehen ist.

Andere Tipps

Nun, wie bei den meisten Dingen davon abhängen. Schauen wir uns die Optionen aussehen

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

Im Fall von TryParse, eine aus param verwenden ist effizient - Sie nicht eine neue Art zu schaffen, haben die 16B von Overhead (auf 32b Maschinen) sein würde oder die perf Kosten entstehen der mit ihnen Müll gesammelt Beitrag des Anruf. TryParse könnte innerhalb einer Schleife zum Beispiel genannt werden - so aus params Regel hier
. Für Funktionen, die nicht innerhalb einer Schleife aufgerufen werden würden (das heißt Leistung ist kein großes Problem), ein einziges zusammengesetztes Objekts Rückkehr könnte ‚sauberere‘ (subjektiver den Betrachter) sein. Jetzt mit anonymen Typen und dynamische Typisierung, könnte sich noch einfacher.

Hinweis:

  1. out params einige Regeln haben, die befolgt werden müssen, das heißt der Compiler dafür sorgen, dass die Funktion den Wert tut initialisieren, bevor es beendet wird. So TryParse hat die aus param auf einen Wert gesetzt werden, auch wenn Parse-Vorgang ist fehlgeschlagen
  2. Die TryXXX Muster ist ein gutes Beispiel dafür, wenn params verwenden aus - Int32.TryParse eingeführt wurde Coz Menschen des perf Hit beschwerte Ausnahmen zu fangen zu wissen, ob Parsing fehlgeschlagen. Auch die am ehesten, was Sie für den Fall, Parse tun würde gelungen, ist die analysierte Wert zu erhalten - eine aus param bedeutet, dass Sie müssen nicht eine andere Methode Anruf parsen

Ich denke, out ist nützlich für Situationen, in denen Sie benötigen sowohl einen boolean und einen Wert zurückgeben, wie TryParse, aber es wäre schön, wenn der Compiler so etwas wie dies erlauben würde:

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

Auf jeden Fall, out-Parameter sollen verwendet werden, wenn Sie eine Methode, die mehr als einen Wert zurückgeben muß, in dem Beispiel, das Sie geschrieben:

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

Es ist nicht viel Sinn macht, einen Out-Parameter zu verwenden, da Sie nur einen Wert zurückgeben, und das Verfahren verwendet, könnte besser sein, wenn Sie die Out-Parameter entfernen und einen int Rückgabewert setzen:

public int Do(int arg1, int arg2)

Es gibt einige gute Dinge über out-Parameter:

  1. Ausgabeparameter werden zunächst nicht zugewiesen betrachtet.
    • Parameter Jeder out muss auf jeden Fall, bevor die Methode zurückkehrt zugeordnet werden, der Code wird nicht kompiliert, wenn Sie einen Auftrag entgehen lassen.

Abschließend versuche ich im Grunde verwendet aus params in meinem private API getrennte Arten zu schaffen zu vermeiden mehrere Rückgabewerte zu wickeln, und auf meiner öffentlichen API, ich sie nur auf Methoden, die mit dem Übereinstimmen TryParse Muster.

Jahre zu spät mit einer Antwort, ich weiß. (und ref als auch) ist auch wirklich nützlich, wenn Sie ein neues Objekt nicht Ihre Methode möchten Sie instanziiert zurückzukehren. Dies ist sehr wichtig in High-Performance-Systemen, auf denen Unter Mikrosekunde Leistung für Ihre Methode erreichen wollen. instanziierenden relativ teuer ist aus einem Speicherzugriff Perspektive gesehen.

Erstellen eines Typs nur für Werte Rückkehr klingt mir wenig schmerzhaft :-) Zuerst werde ich einen Typ für die Rückgabe des Werts dann in der Rufmethode erstellen muss ich den Wert der zurückgegebenen Typ der tatsächlichen Variablen zuweisen, die sie braucht.

Out-Parameter sind simipler zu verwenden.

Ja, ist es sinnvoll. Nehmen Sie dies zum Beispiel.

String strNum = "-1";
Int32 outNum;

if (Int32.TryParse(strNum, out outNum)) {
    // success
}
else {
    // fail
}

Was könnten Sie zurück, wenn der Betrieb in einer normalen Funktion mit einem Rückgabewert versagt? Sie konnten die meisten sicherlich nicht -1 zurück zu repräsentieren ein scheitern, denn dann gäbe es keine Unterscheidung zwischen dem Wert ausfall Rückkehr und dem tatsächlichen Wert, der für den Anfang analysiert wurde. Aus diesem Grund wir ein Boolean Wert zurück, um zu sehen, ob es erfolgreich war, und wenn es dann haben wir unsere „Rückkehr“ haben Wert sicher bereits zugeordnet.

Es hat mich nicht ärgern, dass ich nicht in null auf die Out-Parameter für die TryParse Funktionen passieren kann.

Still, ziehe ich es in einigen Fällen zu einer neuen Art mit zwei Daten zurück. Vor allem, wenn sie zum größten Teil nicht verwandt sind oder ein Stück nur für einen einzigen Vorgang benötigt nach einem Moment. Wenn ich brauche den resultierenden Wert einer TryParse Funktion speichern ich als einige zufällige ResultAndValue Klasse einen out-Parameter wirklich eher wie mit, die ich habe, zu beschäftigen.

Wenn Sie immer eine Art erstellen, dann können Sie mit einer Menge Unordnung in Ihrer Anwendung beenden.

Wie hier gesagt, ein typischer Anwendungsfall ist eine TrySomething Methode, wo Sie eine Bool als Indikator für den Erfolg zurückkehren wollen und dann dem tatsächlichen Wert. Ich finde auch, dass ein wenig sauber in einer if-Anweisung -. Alle drei Optionen in etwa die gleiche LOC haben sowieso

int myoutvalue;
if(int.TryParse("213",out myoutvalue){
    DoSomethingWith(myoutvalue);
}

vs.

ParseResult<int> myoutvalue = int.TryParse("213");
if ( myoutvalue.Success ) {
    DoSomethingWith(myoutvalue.Value);
}

vs.

int? myoutvalue = int.TryParse("213");
if(myoutvalue.HasValue){
    DoSomethingWith(myoutvalue.Value);
}

Wie für die „Warum nicht ein Nullable Type zurückgeben“: TryParse existiert seit Rahmen 1.x, während Nullable Types kam mit 2,0 (Wie sie Generics benötigen). Warum also unnötig Pause Kompatibilität oder starten Inkonsistenzen zwischen TryParse auf einigen Arten einzuführen? Sie können Ihre eigene Erweiterungsmethode zu duplizieren Funktionalität bereits vorhandenen (Siehe Eric Lipperts Beitrag auf einem nicht verwandten Thema, das einige Gründe zu tun / nicht Sachen tun)

Ein weiterer Anwendungsfall ist, wenn Sie mehr unabhängigen Werte zurückkommen müssen, obwohl, wenn Sie das tun, das einen Alarm auslösen soll, dass Ihre Methode möglicherweise zu viel tut. Auf der anderen Seite, wenn Ihre Methode etwas wie ein teuere Datenbank oder Web-Service-Aufruf ist und Sie das Ergebnis cachen, kann es sinnvoll sein, das zu tun. Natürlich könnten Sie eine Art erstellen, aber wieder, das bedeutet eine weitere Art in Ihrer Anwendung.

ich aus Parameter manchmal zur besseren Lesbarkeit, wenn die Methodennamen zu lesen ist wichtiger als alles, was der Ausgang des Verfahrens ist-insbesondere für Methoden, die Ergebnisse zu Befehle zusätzlich durchführen.

StatusInfo a, b, c;

Initialize(out a);
Validate(a, out b);
Process(b, out c);

vs.

StatusInfo a = Initialize();
StatusInfo b = Validate(a);
StatusInfo c = Process(b);

Zumindest für mich, habe ich sehr viel Wert auf den ersten Buchstaben jeder Zeile, wenn ich scannen. Ich kann leicht sagen, was im ersten Beispiel los ist nach der Erkenntnis, dass einige „Statusinfo“ Variablen deklariert sind. Im zweiten Beispiel, das erste, was ich sehe, ist, dass eine Reihe von Statusinfo abgerufen wird. Ich habe ein zweites Mal scannen, um zu sehen, welche Art von Auswirkungen können die Verfahren haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top