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?

6voto

Ali Jamal Punkte 794

Sie können die out kontextuelles Schlüsselwort in zwei Kontexten (jeder ist ein Link zu detaillierten Informationen), als Parameter-Modifikator oder in generischen Typparameter-Deklarationen in Schnittstellen und Delegaten. In diesem Thema wird der Parameter-Modifikator behandelt, aber Sie können dieses andere Thema für Informationen über die generischen Typ-Parameter-Deklarationen sehen.

En out Schlüsselwort bewirkt, dass Argumente per Referenz übergeben werden. Dies ist wie das ref Schlüsselwort, mit der Ausnahme, dass ref erfordert, dass die Variable initialisiert wird, bevor sie übergeben wird. Zur Verwendung einer out Parameter zu verwenden, müssen sowohl die Methodendefinition als auch die aufrufende Methode ausdrücklich den out Stichwort. Zum Beispiel: C#

class OutExample
{
    static void Method(out int i)
    {
        i = 44;
    }
    static void Main()
    {
        int value;
        Method(out value);
        // value is now 44
    }
}

Obwohl Variablen, die als out Argumente nicht initialisiert werden müssen, bevor sie übergeben werden, muss die aufgerufene Methode einen Wert zuweisen, bevor die Methode zurückkehrt.

Obwohl die ref y out Schlüsselwörter ein anderes Laufzeitverhalten verursachen, werden sie zur Kompilierzeit nicht als Teil der Methodensignatur betrachtet. Daher können Methoden nicht überladen werden, wenn der einzige Unterschied darin besteht, dass eine Methode ein ref Argument und das andere nimmt ein out Argument. Der folgende Code wird zum Beispiel nicht kompiliert: C#

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

Eine Überladung kann jedoch erfolgen, wenn eine Methode eine ref o out Argument und das andere keines, wie hier: C#

class OutOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(out int i) { i = 5; }
}

Eigenschaften sind keine Variablen und können daher nicht als out Parameter.

Informationen zur Übergabe von Arrays finden Sie unter Übergabe von Arrays mit ref y out (C# Programmierhandbuch).

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

Async methods, which you define by using the async modifier.

Iterator methods, which include a yield return or yield break statement.

Exemple

Die Erklärung eines out Methode ist nützlich, wenn Sie möchten, dass eine Methode mehrere Werte zurückgibt. Das folgende Beispiel verwendet out um mit einem einzigen Methodenaufruf drei Variablen zurückzugeben. Beachten Sie, dass das dritte Argument Null zugewiesen wird. Dies ermöglicht es den Methoden, optional Werte zurückzugeben. C#

class OutReturnExample
{
    static void Method(out int i, out string s1, out string s2)
    {
        i = 44;
        s1 = "I've been returned";
        s2 = null;
    }
    static void Main()
    {
        int value;
        string str1, str2;
        Method(out value, out str1, out str2);
        // value is now 44
        // str1 is now "I've been returned"
        // str2 is (still) null;
    }
}

5voto

ParmesanCodice Punkte 4992

Nur um die Bemerkung des Auftraggebers klarzustellen, dass die Verwendung von ref und out ein "Verweis auf einen Werttyp oder eine Struktur, die außerhalb der Methode deklariert wurde" ist, was bereits unrichtig festgestellt wurde.

Betrachten Sie die Verwendung von ref bei einem StringBuilder, der ein Referenztyp ist:

private void Nullify(StringBuilder sb, string message)
{
    sb.Append(message);
    sb = null;
}

// -- snip --

StringBuilder sb = new StringBuilder();
string message = "Hi Guy";
Nullify(sb, message);
System.Console.WriteLine(sb.ToString());

// Output
// Hi Guy

Im Gegensatz zu diesem:

private void Nullify(ref StringBuilder sb, string message)
{
    sb.Append(message);
    sb = null;
}

// -- snip --

StringBuilder sb = new StringBuilder();
string message = "Hi Guy";
Nullify(ref sb, message);
System.Console.WriteLine(sb.ToString());

// Output
// NullReferenceException

5voto

CharithJ Punkte 44196

Im Grunde genommen sind beide ref y out zur Übergabe von Objekt/Wert zwischen Methoden

Das Schlüsselwort out bewirkt, dass die Argumente als Referenz übergeben werden. Dies entspricht dem Schlüsselwort ref, mit dem Unterschied, dass ref erfordert, dass die Variable initialisiert wird, bevor sie übergeben wird.

out : Das Argument ist nicht initialisiert und muss in der Methode initialisiert werden

ref : Das Argument ist bereits initialisiert und kann in der Methode gelesen und aktualisiert werden.

Was bedeutet "ref" für Referenztypen?

Sie können die angegebene Referenz in eine andere Instanz ändern.

Wussten Sie das?

  1. Obwohl die Schlüsselwörter ref und out ein unterschiedliches Laufzeitverhalten verursachen, werden sie zur Kompilierzeit nicht als Teil der Methodensignatur betrachtet. Daher können Methoden nicht überladen werden, wenn der einzige Unterschied darin besteht, dass eine Methode ein ref-Argument und die andere ein out-Argument annimmt.

  2. Sie können die Schlüsselwörter ref und out nicht für die folgenden Arten von Methoden verwenden:

    • Async-Methoden, die Sie mit dem async-Modifikator definieren.
    • Iterator-Methoden, die eine yield return- oder yield break-Anweisung enthalten.
  3. Eigenschaften sind keine Variablen und können daher nicht als Out-Parameter übergeben werden.

4voto

vml19 Punkte 3744

Ein als ref übergebenes Argument muss vor der Übergabe an die Methode initialisiert werden, während out-Parameter vor der Übergabe an eine Methode nicht initialisiert werden müssen.

4voto

RayLoveless Punkte 17624

Warum wollen Sie überhaupt etwas benutzen?

Um andere wissen zu lassen, dass die Variable initialisiert wird, wenn sie von der aufgerufenen Methode zurückkehrt!

Wie oben erwähnt: "für einen Out-Parameter, die aufrufende Methode muss einen Wert zuweisen, bevor die Methode zurückkehrt ."

Beispiel:

Car car;
SetUpCar(out car);
car.drive();  // You know car is initialized.

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