2339 Stimmen

Was ist der beste Weg, um eine C# Auto-Eigenschaft einen Anfangswert zu geben?

Wie gibt man einer C#-Auto-Eigenschaft einen Anfangswert?

Entweder verwende ich den Konstruktor, oder ich greife auf die alte Syntax zurück.

Verwendung des Konstruktors:

class Person 
{
    public Person()
    {
        Name = "Initial Name";
    }
    public string Name { get; set; }
}

Verwendung der normalen Eigenschaftssyntax (mit einem Anfangswert)

private string name = "Initial Name";
public string Name 
{
    get 
    {
        return name;
    }
    set
    {
        name = value;
    }
}

Gibt es einen besseren Weg?

46voto

Habib Punkte 211435

Beginnend mit C# 6.0 Wir können den automatisch implementierten Eigenschaften Standardwerte zuweisen.

public string Name { get; set; } = "Some Name";

Wir können auch eine schreibgeschützte, automatisch implementierte Eigenschaft erstellen wie:

public string Name { get; } = "Some Name";

Siehe: C# 6: Erste Reaktionen , Initialisierer für automatisch implementierte Eigenschaften - Von Jon Skeet

45voto

codez0mb1e Punkte 466

Unter C# 9.0 war zusätzliche Unterstützung de init Stichwort - sehr nützlich und äußerst raffinierte Art für die Deklaration schreibgeschützte Auto-Eigenschaften :

Erklären:

class Person 
{ 
    public string Name { get; init; } = "Anonymous user";
}

~Enjoy~ Verwenden:

// 1. Person with default name
var anonymous = new Person();
Console.WriteLine($"Hello, {anonymous.Name}!");
// > Hello, Anonymous user!

// 2. Person with assigned value
var me = new Person { Name = "@codez0mb1e"};
Console.WriteLine($"Hello, {me.Name}!");
// > Hello, @codez0mb1e!

// 3. Attempt to re-assignment Name
me.Name = "My fake"; 
// > Compilation error: Init-only property can only be assigned in an object initializer

7 Stimmen

Früher konnten wir einfach public string Name { get; } = "Anonymous user"; die Implementierung der Version 9 ist nützlicher, um den Bereich zu erweitern, in dem Sie die Werte noch festlegen können. Diese Antwort suggeriert, dass wir auf C# 9 warten müssen, was für das erwartete Verhalten von OPs einfach nicht stimmt.

39voto

ANewGuyInTown Punkte 4921

In Version von C# (6.0) und höher können Sie tun:

Für Readonly-Eigenschaften

public int ReadOnlyProp => 2;

Sowohl für beschreibbare als auch für lesbare Eigenschaften

public string PropTest { get; set; } = "test";

In der aktuellen Version von C# (7.0) (Das Snippet zeigt vielmehr, wie Sie ausdrucksbasierte get/set-Accessors verwenden können, um bei der Verwendung mit Backing-Feldern kompakter zu sein)

private string label = "Default Value";

// Expression-bodied get / set accessors.
public string Label
{
   get => label;
   set => this.label = value; 
 }

8 Stimmen

Beachten Sie auch das Beispiel class C { public DateTime P { get; } = DateTime.Now; public DateTime Q => DateTime.Now; } wobei beide Eigenschaften P y Q haben nur einen Getter, aber die Verhaltensweisen von P y Q sind sehr unterschiedlich!

23voto

brakeroo Punkte 1249

Zusätzlich zu der bereits akzeptierten Antwort sollten Sie für den Fall, dass Sie eine Standardeigenschaft als Funktion von anderen Eigenschaften, die Sie verwenden können Ausdruckskörper-Notation auf C#6.0 (und höher) für noch elegantere und prägnantere Konstrukte wie:

public class Person{

    public string FullName  => $"{First} {Last}"; // expression body notation

    public string First { get; set; } = "First";
    public string Last { get; set; } = "Last";
}

Sie können die obigen Angaben auf folgende Weise verwenden

    var p = new Person();

    p.FullName; // First Last

    p.First = "Jon";
    p.Last = "Snow";

    p.FullName; // Jon Snow

Um die obige "=>"-Notation verwenden zu können, muss die Eigenschaft nur lesbar sein, und Sie verwenden nicht das Accessor-Schlüsselwort get.

Einzelheiten zu MSDN

0 Stimmen

FullName ist eine berechnet Eigenschaft ohne Hintergrundfeld, so dass dies nicht wirklich die Frage beantwortet, die sich auf automatische Eigenschaften bezieht.

15voto

Lex Punkte 638

In C# 6 und höher können Sie einfach die Syntax verwenden:

public object Foo { get; set; } = bar;

Beachten Sie, dass eine readonly Eigenschaft einfach die Menge weglassen, wie so:

public object Foo { get; } = bar;

Sie können auch zuweisen readonly Auto-Eigenschaften aus dem Konstruktor.

Zuvor hatte ich wie folgt geantwortet.

Ich würde es vermeiden, dem Konstruktor eine Vorgabe hinzuzufügen; überlassen Sie das dynamischen Zuweisungen und vermeiden Sie zwei Punkte, an denen die Variable zugewiesen wird (d. h. die Typvorgabe und im Konstruktor). Normalerweise würde ich in solchen Fällen einfach eine normale Eigenschaft schreiben.

Eine andere Möglichkeit besteht darin, wie in ASP.Net Standardwerte über ein Attribut zu definieren:

http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx

1 Stimmen

Wow, das ist ein Schlag in die Vergangenheit. Ich glaube mich zu erinnern, dass dies auf der Lektüre der Spezifikation beruhte (ein Teilauszug hier: msdn.microsoft.com/de-us/library/aa645756(v=vs.71).aspx ). In Anbetracht der Zeit und der Anzahl der Versionen (und Roslyn) könnte dies durchaus nicht mehr der Fall sein. Eine Gegenreferenz wäre allerdings sehr willkommen.

1 Stimmen

Die Standardzuweisung erfolgt automatisch, unabhängig davon, ob Sie einen Anfangswert oder eine Zuweisung im Konstruktor verwenden oder nicht. Es gibt einen kleinen semantischen Unterschied - Feldzuweisungen erfolgen vor Konstruktoraufrufen - aber die Null-Zuweisung wird trotzdem erfolgen. Siehe 10.4.5 "alle Instanzfelder...werden zuerst auf ihre Standardwerte initialisiert, und dann werden die Instanzfeldinitialisierer ausgeführt" msdn.microsoft.com/de-us/library/aa645757(VS.71).aspx

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