Was ist das? einstellen; } Syntax in C #?


577

Ich lerne ASP.NET MVC und kann englische Dokumente lesen, aber ich verstehe nicht wirklich, was in diesem Code passiert:

public class Genre
{
    public string Name { get; set; }
}

Was bedeutet das : { get; set; }?


4
Denken Sie im Allgemeinen daran, dass Setter Ihr Objekt veränderlich machen, eine schlechte Idee. Getter verletzen "Sagen Sie einem Objekt, was zu tun ist, fragen Sie es nicht nach Informationen und manipulieren Sie es selbst". Fügen Sie also im Allgemeinen nicht standardmäßig Setter und Getter hinzu. Sie werden sie oft brauchen, aber Sie sollten immer einen echten Bedarf finden, bevor Sie sie hinzufügen. Insbesondere sollten Setter fast nie im Produktionscode verwendet werden (Streben Sie nach Unveränderlichkeit, wo immer dies möglich ist, und wenn eine Mutation erforderlich ist, sollten Sie sie bitten, für Sie zu mutieren, keinen Wert festzulegen).
Bill K

8
Nur um etwas hinzuzufügen ... Wenn Sie nicht setzen {get; set;}, erstellen Sie ein Feld, aber wenn Sie das {get; set;}setzen, erstellen Sie eine Eigenschaft . Eine Immobilie zu haben, könnte einige Dinge einfacher machen, insbesondere wenn Sie mit Reflection arbeiten.
Seichi

@Seichi, der einen Get-Setter verwendet, erstellt auch ein Feld, das jedoch ausgeblendet, als privat deklariert und durch die automatisch erstellten Eigenschaften geändert wird. all das vom Compiler gemacht.
Jonathan Ramos

1
Sind automatische Eigenschaften nicht gegen den Zweck privater Felder gerichtet?
Mireazma

Antworten:


567

Es handelt sich um eine sogenannte Auto-Eigenschaft, die im Wesentlichen eine Abkürzung für Folgendes ist (ähnlicher Code wird vom Compiler generiert):

private string name;
public string Name
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}

93
Klaus, kannst du erklären, was mit diesem Code passieren wird? Es könnte von einer gründlicheren Erklärung profitieren.
TylerH

3
Also, nur um sicher zu gehen: Es ist, als hätte ich den =Operator überladen , aber nur für ein bestimmtes Element, oder?
Hi-Angel

9
Warum brauchen wir die private var. :-/ Schande.
Oliver Dixon

2
@TylerH Der Grund für die private Variable ist die Kapselung. Get / set bietet ein "Gate" zum Abrufen oder Setzen der Variablen. Obwohl es viele Gründe gibt, get / setters nicht zu verwenden, weil das "Gate" die Kapselung der privaten Variablen unterbrechen kann. (es sollte nicht zugänglich sein)
Alexander

4
Es mag offensichtlich sein, aber ich möchte klarstellen, dass die Kurzschrift keine wörtliche Abkürzung dafür ist. Das heißt, es wird keine private Variable nameerstellt. Wenn Sie versucht haben, auf diese private Variable innerhalb der Klasse zu verweisen, schlägt dies fehl. Ich bin nicht sicher, wie C # das macht, aber es verhält sich so, als ob es eine private Variable ohne Namen gibt, auf die Sie in Ihrem Code nicht zugreifen können.
Denziloe

432

Soweit ich weiß, { get; set; }handelt es sich um eine "Auto-Eigenschaft", die genau wie @Klaus und @Brandon eine Abkürzung für das Schreiben einer Eigenschaft mit einem "Hintergrundfeld" darstellt. Also in diesem Fall:

public class Genre
{
    private string name; // This is the backing field
    public string Name   // This is your property
    {
        get => name;
        set => name = value;
    }
}

Wenn Sie jedoch wie ich sind - vor ungefähr einer Stunde -, verstehen Sie die Eigenschaften und Accessoren nicht wirklich und haben auch nicht das beste Verständnis für einige grundlegende Terminologien. MSDN ist ein großartiges Werkzeug, um solche Dinge zu lernen, aber für Anfänger ist es nicht immer leicht zu verstehen. Also werde ich versuchen, dies hier ausführlicher zu erklären.

getund setsind Accessoren , dh sie können auf Daten und Informationen in privaten Feldern zugreifen (normalerweise über ein Hintergrundfeld ) und dies normalerweise über öffentliche Eigenschaften (wie Sie im obigen Beispiel sehen können).

Es ist nicht zu leugnen, dass die obige Aussage ziemlich verwirrend ist, also gehen wir auf einige Beispiele ein. Angenommen, dieser Code bezieht sich auf Musikgenres. Innerhalb des Klassengenres werden wir also verschiedene Musikgenres wollen. Angenommen, wir möchten drei Genres haben: Hip Hop, Rock und Country. Dazu verwenden wir den Namen der Klasse , um neue Instanzen dieser Klasse zu erstellen .

Genre g1 = new Genre(); //Here we're creating a new instance of the class "Genre"
                        //called g1. We'll create as many as we need (3)
Genre g2 = new Genre();
Genre g3 = new Genre();

//Note the () following new Genre. I believe that's essential since we're creating a
//new instance of a class (Like I said, I'm a beginner so I can't tell you exactly why
//it's there but I do know it's essential)

Nachdem wir die Instanzen der Genre-Klasse erstellt haben, können wir die Genre-Namen mithilfe der oben festgelegten Eigenschaft 'Name' festlegen.

public string Name //Again, this is the 'Name' property
{ get; set; } //And this is the shorthand version the process we're doing right now 

Wir können den Namen 'g1' auf Hip Hop setzen, indem wir Folgendes schreiben

g1.Name = "Hip Hop";

Was hier passiert, ist ziemlich komplex. Wie ich bereits sagte, getund setgreifen Sie auf Informationen aus privaten Feldern zu, auf die Sie sonst nicht zugreifen könnten. getkann nur Informationen aus diesem privaten Feld lesen und zurückgeben. setkann nur Informationen in dieses private Feld schreiben . Aber wenn wir eine Eigenschaft mit beiden haben getund setbeide Funktionen ausführen können. Und indem g1.Name = "Hip Hop";wir schreiben, verwenden wir speziell die setFunktion aus unserer Name-Eigenschaft

setverwendet eine implizite Variable namens value. Grundsätzlich bedeutet dies, dass jedes Mal, wenn Sie "Wert" darin sehen set, es sich auf eine Variable bezieht; die Variable "Wert". Wenn wir schreiben, verwenden g1.Name =wir das =, um die valueVariable zu übergeben, die in diesem Fall ist "Hip Hop". Sie können sich das also im Wesentlichen so vorstellen:

public class g1 //We've created an instance of the Genre Class called "g1"
{
    private string name;
    public string Name
    {
        get => name;
        set => name = "Hip Hop"; //instead of 'value', "Hip Hop" is written because 
                              //'value' in 'g1' was set to "Hip Hop" by previously
                              //writing 'g1.Name = "Hip Hop"'
    }
}

Es ist wichtig zu beachten, dass das obige Beispiel nicht tatsächlich im Code geschrieben ist. Es ist eher ein hypothetischer Code, der darstellt, was im Hintergrund vor sich geht.

So , jetzt haben wir haben festgelegt , den Namen der g1 Instanz Genre , glaube ich , können wir erhalten den Namen von Schrift

console.WriteLine (g1.Name); //This uses the 'get' function from our 'Name' Property 
                             //and returns the field 'name' which we just set to
                             //"Hip Hop"

und wenn wir dies ausführen würden, würden wir "Hip Hop"in unsere Konsole bekommen.

Zum Zweck dieser Erklärung werde ich das Beispiel auch mit Ausgaben vervollständigen

using System;
public class Genre
{
    public string Name { get; set; }
}

public class MainClass
{
    public static void Main()
    {
        Genre g1 = new Genre();
        Genre g2 = new Genre();
        Genre g3 = new Genre();

        g1.Name = "Hip Hop";
        g2.Name = "Rock";
        g3.Name = "Country";

        Console.WriteLine ("Genres: {0}, {1}, {2}", g1.Name, g2.Name, g3.Name);
    }
}

Ausgabe:

"Genres: Hip Hop, Rock, Country"

18
Persönlich würde ich es einfach als solches set{name = value;} // 'value' here is equal to "Hip Hop"
auskommentieren

2
@iLoveUnicorns, es dient der Datenabstraktion . Das Hintergrundfeld enthält die tatsächlichen Daten. Die Eigenschaftsdefinition definiert tatsächlich, wie mit den Methoden getund auf die Daten zugegriffen wird set. Der Link, den ich bereitgestellt habe, enthält ein hervorragendes Zitat von John Guttag oben auf der Seite. Ich würde empfehlen, sein Buch zu lesen oder sogar an diesem kostenlosen Online-Kurs
Josie Thompson

2
Können wir nicht einfach verwenden: public class Genre{public string Name;} anstelle von : public class Genre{ public string Name { get; set; }}. Ich meine, warum brauchen wir überhaupt {get; einstellen; }?
user2048204

1
Scheint, als ob meine Besorgnis bereits bestätigt wurde. Wenn Sie dies deklarieren: "public string Name {get; set;}" und Sie auf diese Weise zugreifen: g1.Name = "Hip Hop"; - Wo ist dann die Objektorientierung? Ich brauche nicht einmal das sogenannte "Hintergrundfeld". Das Hintergrundfeld existiert für mich nicht einmal. Weil ich nur auf das öffentliche Feld zugreife. Und wenn das öffentliche Feld "öffentlich" ist, ist es nicht OO-konform. Gehen wir alle zurück zu COBOL.
Baruch Atta

1
Tolle Antwort, aber wenn wir pedantisch sind, ist "set" ein Mutator, kein Accessor.
Python

100

Das sind automatische Eigenschaften

Grundsätzlich eine andere Art, eine Eigenschaft mit einem Hintergrundfeld zu schreiben.

public class Genre
{
    private string _name;

    public string Name 
    { 
      get => _name;
      set => _name = value;
    }
}

7
Was heißt "Hintergrundfeld"?
Kn3l

4
@stackunderflow: Im Hintergrundfeld werden die Daten gespeichert. (Was wird bei der Verwendung zurückgegeben getund bleibt bei der Verwendung set). Wie der Schrank, zu dem getund setöffnet die Tür von.
Grant Thomas

5
@stackunderflow: In dieser Antwort lautet das Hintergrundfeld _name. In der automatischen Eigenschaft ist das Hintergrundfeld ausgeblendet.
Justin

36

Dies ist der kurze Weg, um dies zu tun:

public class Genre
{
    private string _name;

    public string Name
    {
      get => _name;
      set => _name = value;
    }
}

33

Es ist eine Verknüpfung, um Datenelemente als öffentlich verfügbar zu machen, sodass Sie keine expliziten privaten Datenelemente erstellen müssen. C # erstellt ein privates Datenelement für Sie.

Sie könnten Ihre Datenelemente einfach öffentlich machen, ohne diese Verknüpfung zu verwenden. Wenn Sie jedoch die Implementierung des Datenelements ändern möchten, um eine gewisse Logik zu erhalten, müssen Sie die Schnittstelle unterbrechen. Kurz gesagt, es ist eine Abkürzung, um flexibleren Code zu erstellen.


2
Kelsey - können Sie erklären, wie diese Syntax den Code "flexibler" macht? Ich sehe es nicht Wenn Sie dem Setter oder Getter eine "Logik" hinzufügen würden, würden Sie im Ether-Fall (mit oder ohne private Daten) die Schnittstelle so wie sie ist immer noch beschädigen und eine Codierung benötigen.
Baruch Atta

18

Grundsätzlich ist es eine Abkürzung von:

class Genre{
    private string genre;
    public string getGenre() {
        return this.genre;
    }
    public void setGenre(string theGenre) {
        this.genre = theGenre;
    }
}
//In Main method
genre g1 = new Genre();
g1.setGenre("Female");
g1.getGenre(); //Female

5
Dies beantwortet die Frage nicht. Das OP sprach über Eigenschaften.
theB

6
Ich kenne die Eigenschaften Get and Set, es ist ein Beispiel, das hilft, besser zu verstehen
Jirson Tavera


6

Sie sind die Accessoren für den Namen des öffentlichen Eigentums.

Sie würden sie verwenden, um den Wert dieser Eigenschaft in einer Instanz von Genre abzurufen / festzulegen.


6

Das ist eine automatisch implementierte Eigenschaft. Dies ist im Grunde eine Kurzform zum Erstellen von Eigenschaften für eine Klasse in C #, ohne dass private Variablen für diese definiert werden müssen. Sie werden normalerweise verwendet, wenn beim Abrufen oder Festlegen des Werts einer Variablen keine zusätzliche Logik erforderlich ist.

Weitere Informationen finden Sie im Programmierhandbuch für automatisch implementierte Eigenschaften von MSDN .


6
  • Das get / set-Muster bietet eine Struktur, mit der Logik während des Einstellens ('set') oder Abrufens ('get') einer Eigenschaftsinstanz einer instanziierten Klasse hinzugefügt werden kann. Dies kann nützlich sein, wenn eine Instanziierungslogik für die erforderlich ist Eigentum.

  • Eine Eigenschaft kann nur einen 'get'-Accessor haben, der ausgeführt wird, um diese Eigenschaft schreibgeschützt zu machen

  • Bei der Implementierung eines get / set-Musters wird eine Zwischenvariable als Container verwendet, in den ein Wert eingefügt und ein Wert extrahiert werden kann. Der Zwischenvariablen wird normalerweise ein Unterstrich vorangestellt. Diese Zwischenvariable ist privat, um sicherzustellen, dass nur über ihre get / set-Aufrufe auf sie zugegriffen werden kann. Siehe die Antwort von Brandon, da seine Antwort die am häufigsten verwendeten Syntaxkonventionen für die Implementierung von get / set zeigt.


5

Dies bedeutet, dass Sie beim Erstellen einer Variablen vom Typ Genre auf die Variable als Eigenschaft zugreifen können

Genre oG = new Genre();
oG.Name = "Test";

5
Wenn Sie keine automatisch implementierten Eigenschaften verwenden, können Sie auf diese Weise trotzdem darauf zugreifen. Bei AIP geht es nicht um den Zugriff von außen, sondern um die Deklaration innerhalb einer Klasse.
Abatishchev

4

Eine solche { get; set; }Syntax wird als automatische Eigenschaften, C # 3.0-Syntax, bezeichnet

Zum Kompilieren müssen Sie Visual C # 2008 / csc v3.5 oder höher verwenden. Sie können jedoch Ausgaben kompilieren, die auf nur .NET Framework 2.0 abzielen (keine Laufzeit oder Klassen erforderlich, um diese Funktion zu unterstützen).


4

Wenn Sie Xin Visual Studio eine Eigenschaft in einer Klasse definieren und diese Klasse nur als Typ verwenden möchten, erhalten Sie nach dem Erstellen Ihres Projekts eine Warnung mit der Meldung "Feld X wird niemals zugewiesen und hat immer seine Standardeinstellung Wert " .

Durch das Hinzufügen einer { get; set; }auf XEigenschaft, werden Sie diese Warnung nicht erhalten.

Darüber hinaus können Sie in Visual Studio 2013 und höheren Versionen durch Hinzufügen { get; set; }alle Verweise auf diese Eigenschaft anzeigen.

Geben Sie hier die Bildbeschreibung ein


4

Es ist im Grunde eine Abkürzung. Sie können public string Name { get; set; }wie in vielen Beispielen schreiben , aber Sie können es auch schreiben:

private string _name;

public string Name
{
    get { return _name; }
    set { _name = value ; } // value is a special keyword here
}

Warum wird es verwendet? Es kann verwendet werden, um den Zugriff auf eine Eigenschaft zu filtern. Beispielsweise möchten Sie nicht, dass Namen Zahlen enthalten.

Lassen Sie mich Ihnen ein Beispiel geben:

private class Person {
    private int _age;  // Person._age = 25; will throw an error
    public int Age{
        get { return _age; }  // example: Console.WriteLine(Person.Age);
        set { 
            if ( value >= 0) {
                _age = value; }  // valid example: Person.Age = 25;
        }
    }
}

Offiziell heißt es Auto-Implemented Properties und es ist eine gute Angewohnheit, das ( Programmierhandbuch ) zu lesen . Ich würde auch Tutorial Video C # Eigenschaften empfehlen : Warum "get" und "set" verwenden .


2

Get set sind Zugriffsmodifikatoren auf die Eigenschaft. Get liest das Eigenschaftsfeld. Set legt den Eigenschaftswert fest. Get ist wie ein schreibgeschützter Zugriff. Set ist wie Schreibzugriff. Um die Eigenschaft als Lese- und Schreibzugriff zu verwenden, müssen sowohl get als auch set verwendet werden.


1
Ich denke, get set sind keine Zugriffsmodifikatoren, sondern Accessoren. Zugriffsmodifikatoren sind wie folgt: öffentlich, privat, intern usw.
Rohit Arora

1

Get wird aufgerufen, wenn die Eigenschaft auf der rechten Seite (RHS) angezeigt wird. Set wird aufgerufen, wenn die Eigenschaft auf der linken Seite (LHS) des Symbols '=' angezeigt wird

Bei einer automatisch implementierten Eigenschaft funktioniert das Hintergrundfeld hinter den Kulissen und ist nicht sichtbar.

Beispiel:

public string Log { get; set; }

Während für eine nicht automatisch implementierte Eigenschaft das Hintergrundfeld im Voraus angezeigt wird und als Variable mit privatem Bereich sichtbar ist.

Beispiel:

private string log;

public string Log
{
    get => log;
    set => log = value;
}

Es ist auch erwähnenswert, dass hier der "Getter" und der "Setter" das unterschiedliche "Hintergrundfeld" verwenden können.


Dies scheint die gestellte Frage nicht zu beantworten.
TylerH

Hinweis zum Zeitpunkt des Aufrufs von get & set. Alle oben genannten Antworten erwecken den Eindruck, dass das Hintergrundfeld für get & set dasselbe ist. Dies ist jedoch nicht der Fall. Meine Antwort ist also sehr relevant für die Hauptfrage. Hoffe du stimmst mir zu.
Bala

Für eine automatisch generierte Eigenschaft, nach der in der Frage gefragt wird, dürfen für den Getter und den Setter keine unterschiedlichen Hintergrundfelder verwendet werden. Es gibt nur ein Hintergrundfeld. Für eine nicht automatische Eigenschaft (nach der die Frage nicht fragt) gibt es möglicherweise überhaupt kein konzeptionelles Hintergrundfeld. Außerdem können Sie ein Programm mit einem Getter auf der linken Seite eines Zuweisungsoperators und eines mit einem Setter auf der rechten Seite eines Zuweisungsoperators schreiben. Alle diese Informationen beantworten also nicht nur nicht die gestellte Frage, sondern sind auch falsch.
Servy

0

Definieren Sie die privaten Variablen

Im Konstruktor und laden Sie die Daten

Ich habe eine Konstante erstellt und lade die Daten von der Konstanten in die Klasse Ausgewählte Liste.

public  class GridModel
{
    private IEnumerable<SelectList> selectList;
    private IEnumerable<SelectList> Roles;

    public GridModel()
    {
        selectList = from PageSizes e in Enum.GetValues(typeof(PageSizes))
                       select( new SelectList()
                       {
                           Id = (int)e,
                           Name = e.ToString()
                       });

        Roles= from Userroles e in Enum.GetValues(typeof(Userroles))
               select (new SelectList()
               {
                   Id = (int)e,
                   Name = e.ToString()
               });
    }

  public IEnumerable<SelectList> Pagesizelist { get { return this.selectList; } set { this.selectList = value; } } 
  public IEnumerable<SelectList> RoleList { get { return this.Roles; } set { this.Roles = value; } }
  public IEnumerable<SelectList> StatusList { get; set; }

}

0

Eine Eigenschaft ähnelt einer Ebene, die die private Variable von anderen Mitgliedern einer Klasse trennt. Von außen fühlt es sich so an, als sei eine Eigenschaft nur ein Feld. Auf eine Eigenschaft kann mit .Property zugegriffen werden

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName => $"{FirstName} {LastName}";
}

public class Person
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return $"{FirstName} {LastName}"; } }
}

FullName ist eine Eigenschaft. Der mit dem Pfeil ist eine Abkürzung. Von außerhalb können wir wie folgt auf FullName zugreifen:

var person = new Person();
Console.WriteLine(person.FullName);

Anrufer interessieren sich nicht dafür, wie Sie den vollständigen Namen implementiert haben. Aber innerhalb der Klasse können Sie FullName ändern, was Sie wollen.

Weitere Informationen finden Sie in der Microsoft-Dokumentation:

https://docs.microsoft.com/en-us/dotnet/csharp/properties

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.