Übergeben einer Eigenschaft als 'out'-Parameter in C #

80

Angenommen, ich habe:

public class Bob
{
    public int Value { get; set; }
}

Ich möchte das Value- Member als out-Parameter wie übergeben

Int32.TryParse("123", out bob.Value);

Ich erhalte jedoch den Kompilierungsfehler "Das Argument 'out' wird nicht als Variable klassifiziert." Gibt es eine Möglichkeit, dies zu erreichen, oder muss ich eine Variable à la extrahieren:

int value;
Int32.TryParse("123", out value);
bob.Value = value;
dornig
quelle

Antworten:

82

Sie müssten explizit ein Feld und eine "normale" Eigenschaft anstelle einer automatisch implementierten Eigenschaft verwenden:

public class Bob
{
    private int value;
    public int Value
    { 
        get { return value; } 
        set { this.value = value; }
    }
}

Dann können Sie das Feld als out-Parameter übergeben:

Int32.TryParse("123", out bob.value);

Aber das funktioniert natürlich nur innerhalb derselben Klasse, da das Feld privat ist (und sein sollte!).

Eigenschaften lassen Sie dies einfach nicht zu. Auch in VB , wo Sie können eine Eigenschaft über einen Verweis oder verwenden Sie es als out - Parameter, gibt es im Grunde eine zusätzliche temporäre Variable.

Wenn Sie sich nicht für den Rückgabewert von interessieren TryParse, können Sie jederzeit Ihre eigene Hilfsmethode schreiben:

static int ParseOrDefault(string text)
{
    int tmp;
    int.TryParse(text, out tmp);
    return tmp;
}

Dann benutze:

bob.Value = Int32Helper.ParseOrDefault("123");

Auf diese Weise können Sie eine einzelne temporäre Variable verwenden, auch wenn Sie dies an mehreren Stellen tun müssen.

Jon Skeet
quelle
1
Ich denke, das Problem mit dem ersten Ansatz ist, dass, wenn Sie das Feld direkt (anstelle der Eigenschaft) verwenden, Sie möglicherweise Validierungsregeln umgehen, die in der Eigenschaft vorhanden sein können
Andreas Grech
3
@ Jon: Ich denke, Sie möchten int.Parse im Beispiel ParseOrDefault in int.TryParse ändern.
Shahkalpesh
8
Übrigens ist der Grund, warum Sie keine Eigenschaft als Ausgabeparameter haben können, dass das Festlegen einer Eigenschaft tatsächlich ein Funktionsaufruf und keine Zuweisung ist, wenn Sie unter die Haube schauen.
Dirk Vollmar
3
Ich würde gerne den richtigen syntaktischen Zucker sehen, damit ich eine Eigenschaft als ref- oder out-Parameter übergeben kann. Lassen Sie uns die Arbeit mit dem Compiler erledigen, er ist schneller als ich.
Ignacio Soler Garcia
1
@SoMoS: Ob es sich um einen Werttyp handelt oder nicht, spielt für meinen Kommentar keine Rolle. Entweder wird eine Änderung der Methode am Parameter sofort wirksam oder nicht. Dies wirkt sich auch darauf aus, was passiert, wenn eine Ausnahme ausgelöst wird.
Jon Skeet
7

Sie können das erreichen, aber nicht mit einer Eigenschaft.

public class Bob {
    public int Value { get; set; } // This is a property

    public int AnotherValue; // This is a field
}

Sie können nicht outauf verwenden Value, aber Sie können auf AnotherValue.

Das wird funktionieren

Int32.TryParse("123", out bob.AnotherValue);

In allgemeinen Richtlinien wird jedoch empfohlen, ein Klassenfeld nicht öffentlich zu machen. Sie sollten also den temporären Variablenansatz verwenden.

Pierre-Alain Vigeant
quelle