417 Stimmen

Wann ist in vs. ref vs. out zu verwenden?

Neulich fragte mich jemand, wann er das Schlüsselwort "Parameter" verwenden sollte out anstelle von ref . Ich verstehe zwar (glaube ich) den Unterschied zwischen dem ref y out Schlüsselwörter (das war vorher gefragt ) und die beste Erklärung scheint zu sein, dass ref == in y out Was sind einige (hypothetische oder Code-) Beispiele, bei denen ich immer out und nicht ref .

Seit ref allgemeiner ist, warum wollen Sie überhaupt die out ? Ist es nur syntaktischer Zucker?

19voto

zneak Punkte 129366

Sie müssen Folgendes verwenden ref wenn Sie den Parameter lesen und beschreiben wollen. Sie müssen out wenn Sie nur schreiben wollen. In der Tat, out ist für den Fall gedacht, dass Sie mehr als einen Rückgabewert benötigen, oder wenn Sie den normalen Rückgabemechanismus für die Ausgabe nicht verwenden wollen (was aber selten der Fall sein sollte).

Es gibt Sprachmechanismen, die diese Anwendungsfälle unterstützen. Ref Parameter müssen initialisiert worden sein, bevor sie an eine Methode übergeben werden (wobei betont wird, dass sie schreibgeschützt sind), und out Parameter können nicht gelesen werden, bevor ihnen ein Wert zugewiesen wurde, und es wird garantiert, dass am Ende der Methode auf sie geschrieben wurde (was die Tatsache unterstreicht, dass sie nur schreibbar sind). Ein Verstoß gegen diese Grundsätze führt zu einem Kompilierzeitfehler.

int x;
Foo(ref x); // error: x is uninitialized

void Bar(out int x) {}  // error: x was not written to

Zum Beispiel, int.TryParse gibt eine bool und akzeptiert eine out int Parameter:

int value;
if (int.TryParse(numericString, out value))
{
    /* numericString was parsed into value, now do stuff */
}
else
{
    /* numericString couldn't be parsed */
}

Dies ist ein klares Beispiel für eine Situation, in der Sie zwei Werte ausgeben müssen: das numerische Ergebnis und ob die Konvertierung erfolgreich war oder nicht. Die Autoren der CLR haben sich für die Methode out hier, da sie sich nicht darum scheren, was die int vorher gewesen sein könnte.

Para ref können Sie sich ansehen Interlocked.Increment :

int x = 4;
Interlocked.Increment(ref x);

Interlocked.Increment inkrementiert atomar den Wert von x . Da Sie lesen müssen x um sie zu erhöhen, ist dies eine Situation, in der ref angemessener ist. Es ist Ihnen völlig egal, was x war, bevor sie an Increment .

In der nächsten Version von C# wird es sogar möglich sein, eine Variable in out Parameter, wodurch ihre reine Ausgabefunktion noch stärker betont wird:

if (int.TryParse(numericString, out int value))
{
    // 'value' exists and was declared in the `if` statement
}
else
{
    // conversion didn't work, 'value' doesn't exist here
}

12voto

tinker Punkte 323

Ich habe immer noch das Bedürfnis nach einer guten Zusammenfassung, und das ist es, was ich mir ausgedacht habe.

Zusammenfassung,

Wenn wir uns im Inneren der Funktion spezifizieren wir auf diese Weise die variabel Kontrolle des Datenzugriffs,

in = R

out = muss W vor R

ref = R+W


Erläuterung,

in

Funktion darf nur READ diese Variable.

out

Die Variable muss nicht zuerst initialisiert werden, weil,
Funktion MUSS SCHREIBEN dazu vor READ .

ref

Funktion kann LESEN/SCHREIBEN auf diese Variable.


Warum wird sie so genannt?

Konzentration auf den Ort, an dem die Daten geändert werden,

in

Die Daten dürfen nur vor der Eingabe der Funktion (in) eingestellt werden.

out

Die Daten dürfen nur vor dem Verlassen der Funktion (out) gesetzt werden.

ref

Die Daten müssen vor der Eingabe der Funktion (in) eingestellt werden.
Die Daten können vor dem Verlassen der Funktion (out) eingestellt werden.

11voto

Sina Lotfi Punkte 2495

Wie zu verwenden in o out o ref in C#?

  • Alle Schlüsselwörter in C# haben die gleiche Funktionalität, aber mit einigen Grenzen .
  • in Argumente können von der aufgerufenen Methode nicht geändert werden.
  • ref Argumente können geändert werden.
  • ref initialisiert werden muss, bevor er vom Aufrufer verwendet wird, kann er in der Methode gelesen und aktualisiert werden.
  • out Argumente müssen vom Aufrufer geändert werden.
  • out Argumente müssen in der Methode initialisiert werden
  • Übergebene Variablen como in Argumente müssen initialisiert werden, bevor sie in einem Methodenaufruf übergeben werden. Die aufgerufene Methode darf dem Argument jedoch keinen Wert zuweisen oder es verändern.

Sie können nicht die in , ref y out Schlüsselwörter für die folgenden Arten von Methoden:

  • Asynchrone Methoden die Sie mit Hilfe der Option async Modifikator.
  • Iterator-Methoden , die eine yield return o yield break Erklärung.

7voto

Shneor Punkte 278

Wie es klingt:

aus \= nur Initialisierung/Füllung eines Parameters (der Parameter muss leer sein), Rückgabe des Parameters aus einfach

ref \= Referenz, Standardparameter (vielleicht mit Wert), aber die Funktion kann ihn ändern.

7voto

leppie Punkte 111830

out ist eine stärker eingeschränkte Version von ref .

In einem Methodenrumpf müssen Sie allen out Parameter, bevor Sie die Methode verlassen. Auch ein einer Methode zugewiesener Wert out wird ignoriert, während der Parameter ref müssen sie zugewiesen werden.

Así que out können Sie tun:

int a, b, c = foo(out a, out b);

何所 ref würde die Zuordnung von a und b erfordern.

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