Qual è il {get; impostato; } sintassi in C #?


577

Sto imparando ASP.NET MVC e posso leggere documenti in inglese, ma non capisco davvero cosa sta succedendo in questo codice:

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

Cosa significa questo { get; set; }?


4
In generale ricorda: i setter rendono il tuo oggetto mutevole, una cattiva idea. i getter violano "Dì a un oggetto cosa fare, non chiedere informazioni e manipolalo da solo". Quindi, in generale, non aggiungere setter e getter per impostazione predefinita. Ne avrai bisogno, spesso, ma dovresti sempre trovare un reale bisogno prima di aggiungerli. In particolare, i setter non dovrebbero quasi mai essere usati nel codice di produzione (cercare l'immutabilità laddove possibile, e quando è necessaria la mutazione, dovresti chiederle di mutare per te, non impostare un valore).
Bill K,

8
Solo per aggiungere qualcosa ... Se non metti {get; set;}stai creando un Campo ma se metti il {get; set;}stai creando una Proprietà . Avere una proprietà potrebbe rendere alcune cose più facili soprattutto quando si lavora con Reflection.
Seichi,

@Seichi usando un get-setter crea anche un Field, ma questo è nascosto, dichiarato privato e modificato dalle proprietà create automaticamente; tutto ciò fatto dal compilatore.
Jonathan Ramos,

1
le proprietà automatiche non annullano lo scopo dei campi privati ?
mireazma,

Risposte:


567

È una cosiddetta proprietà auto ed è essenzialmente una scorciatoia per quanto segue (il codice simile verrà generato dal compilatore):

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

93
Klaus, puoi spiegare cosa accadrà con questo codice? Potrebbe beneficiare di una spiegazione più approfondita.
TylerH,

3
Quindi, per essere sicuro: è come se sovraccaricassi l' =operatore, ma solo per un elemento particolare, giusto?
Ciao Angelo

9
Perché abbiamo bisogno della var privata. : - / vergogna.
Oliver Dixon,

2
@TylerH Il motivo della variabile privata è l'incapsulamento, get / set fornisce un "gate" per ottenere o impostare la variabile. Sebbene ci siano molte ragioni per non usare get / setter perché il "gate" può interrompere l'incapsulamento della variabile privata. (non dovrebbe essere accessibile)
Alexander

4
Può essere ovvio, ma voglio chiarire che la stenografia non è letteralmente una scorciatoia per quello. Cioè, nessuna variabile privata nameviene creata. Se hai provato a fare riferimento a questa variabile privata all'interno della classe, fallirà. Non sono sicuro di come C # lo faccia, ma si comporta come se ci fosse una variabile privata senza nome, a cui non puoi accedere nel tuo codice.
Denziloe,

432

Quindi, per quanto ho capito, si { get; set; }tratta di una "proprietà automatica" che, proprio come @Klaus e @Brandon, è una scorciatoia per la scrittura di una proprietà con un "campo di supporto". Quindi in questo caso:

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

Tuttavia, se sei come me - circa un'ora fa - non capisci davvero quali siano le proprietà e gli accessori e non hai nemmeno la migliore comprensione di alcune terminologie di base. MSDN è un ottimo strumento per apprendere cose come questa, ma non è sempre facile da capire per i principianti. Quindi proverò a spiegarlo più in profondità qui.

gete setsono accessori , il che significa che sono in grado di accedere a dati e informazioni in campi privati (di solito da un campo di supporto ) e di solito lo fanno da proprietà pubbliche (come puoi vedere nell'esempio sopra).

Non si può negare che l'affermazione di cui sopra sia piuttosto confusa, quindi entriamo in alcuni esempi. Supponiamo che questo codice si riferisca a generi musicali. Quindi, all'interno del genere Class, desidereremo diversi generi musicali. Diciamo che vogliamo avere 3 generi: Hip Hop, Rock e Country. Per fare ciò useremmo il nome della classe per creare nuove istanze di quella classe.

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)

Ora che abbiamo creato le istanze della classe Genre, possiamo impostare i nomi dei generi usando la proprietà 'Name' che è stata impostata sopra.

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

Possiamo impostare il nome di 'g1' su Hip Hop scrivendo quanto segue

g1.Name = "Hip Hop";

Quello che sta succedendo qui è piuttosto complesso. Come ho detto prima, gete setaccedi alle informazioni da campi privati ​​a cui altrimenti non saresti in grado di accedere. getpuò solo leggere le informazioni da quel campo privato e restituirle. setpuò solo scrivere informazioni in quel campo privato. Ma avendo una proprietà con entrambi gete setsiamo in grado di fare entrambe queste funzioni. E scrivendo g1.Name = "Hip Hop";stiamo usando specificamente la setfunzione dalla nostra proprietà Name

setusa una variabile implicita chiamata value. Fondamentalmente, ciò significa che ogni volta che vedi "valore" all'interno set, si riferisce a una variabile; la variabile "valore". Quando scriviamo g1.Name =stiamo usando il =per passare la valuevariabile che in questo caso è "Hip Hop". Quindi puoi essenzialmente pensarlo in questo modo:

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"'
    }
}

È importante notare che l'esempio sopra non è effettivamente scritto nel codice. È più un ipotetico codice che rappresenta ciò che sta accadendo in background.

Quindi ora che abbiamo impostato il nome dell'istanza g1 del genere , credo che possiamo ottenere il nome scrivendo

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"

e se avessimo eseguito questo, saremmo arrivati "Hip Hop"nella nostra console.

Quindi, ai fini di questa spiegazione, completerò anche l'esempio con gli output

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);
    }
}

Produzione:

"Genres: Hip Hop, Rock, Country"

18
Personalmente lo commenterei come taleset{name = value;} // 'value' here is equal to "Hip Hop"
maksymiuk

2
@iLoveUnicorns, è lì per l' astrazione dei dati . Il campo di supporto è ciò che contiene i dati effettivi. La definizione della proprietà definisce effettivamente come si accede ai dati con i metodi gete set. Il link che ho fornito ha una citazione eccellente da John Guttag nella parte superiore della pagina. Consiglierei di leggere il suo libro o anche di seguire questo corso online gratuito
Josie Thompson,

2
Non possiamo semplicemente usare: public class Genre{public string Name;} invece di: public class Genre{ public string Name { get; set; }}. Voglio dire, perché abbiamo persino bisogno di {get; impostato; }?
user2048204

1
Sembra che la mia preoccupazione sia già stata ripresa. Se si dichiara in questo modo: "nome stringa pubblica {get; set;}" e si accede in questo modo: g1.Name = "Hip Hop"; - allora dov'è l'Orientamento agli oggetti? Non ho nemmeno bisogno del cosiddetto "campo di appoggio". Il campo di supporto non esiste nemmeno, per quanto mi riguarda. Perché accedo solo al campo pubblico. E se il campo pubblico è "pubblico", non è conforme a OO. Torniamo tutti a COBOL.
Baruch Atta,

1
Ottima risposta, ma se siamo pedanti, "impostare" è un mutatore, non un accessore.
pythlang,

100

Quelle sono proprietà automatiche

Fondamentalmente un altro modo di scrivere una proprietà con un campo di supporto.

public class Genre
{
    private string _name;

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

7
Cosa si chiama "campo di appoggio"?
kn3l

4
@stackunderflow: il campo di supporto è dove sono archiviati i dati. (cosa viene restituito durante l'utilizzo gete uso persistente set). Come l'armadio a cui gete setapre la porta.
Concedi Thomas il

5
@stackunderflow: in questa risposta, il campo di supporto è _name. Nella proprietà automatica, il campo di supporto è nascosto.
Justin,

36

Questo è il modo breve per farlo:

public class Genre
{
    private string _name;

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

33

È una scorciatoia per esporre i membri di dati come pubblici in modo da non dover creare esplicitamente membri di dati privati. C # creerà un membro di dati privato per te.

Potresti semplicemente rendere pubblici i tuoi membri dei dati senza usare questo collegamento, ma se decidi di cambiare l'implementazione del membro dei dati per avere un po 'di logica, dovrai interrompere l'interfaccia. Quindi in breve è una scorciatoia per creare un codice più flessibile.


2
Kelsey - potresti spiegare in che modo questa sintassi rende il codice più "flessibile"? Non lo vedo Se aggiungessi qualche "logica" al setter o al getter, allora nel caso ether (con o senza dati privati), interromperesti comunque l'interfaccia così com'è e avrai bisogno di un po 'di codice.
Baruch Atta,

18

Fondamentalmente, è una scorciatoia di:

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
Questo non risponde alla domanda. L'OP parlava di proprietà.
theB

6
conosco le proprietà Get and Set, è un esempio che aiuta a capire meglio
Jirson Tavera,


6

Sono gli accessori per il nome della proprietà pubblica.

Li useresti per ottenere / impostare il valore di quella proprietà in un'istanza di Genere.


6

Questa è una proprietà implementata automaticamente. È fondamentalmente un modo abbreviato di creare proprietà per una classe in C #, senza dover definire variabili private per esse. Vengono normalmente utilizzati quando non è richiesta alcuna logica aggiuntiva quando si ottiene o si imposta il valore di una variabile.

Puoi leggere ulteriori informazioni sulla Guida alla programmazione delle proprietà implementate automaticamente di MSDN .


6
  • Il modello get / set fornisce una struttura che consente di aggiungere la logica durante l'impostazione ('set') o il recupero ('get') di un'istanza di proprietà di una classe istanziata, che può essere utile quando è richiesta una logica di istanza per proprietà.

  • Una proprietà può avere solo un accesso 'get', che viene fatto per renderla di sola lettura

  • Quando si implementa un modello get / set, una variabile intermedia viene utilizzata come contenitore in cui è possibile inserire un valore e estrarlo. La variabile intermedia è generalmente preceduta da un trattino basso. questa variabile intermedia è privata al fine di garantire che sia possibile accedervi solo tramite le sue chiamate get / set. Vedi la risposta di Brandon, poiché la sua risposta dimostra le convenzioni di sintassi più comunemente usate per implementare get / set.


5

Ciò significa che se crei una variabile di tipo Genere, sarai in grado di accedere alla variabile come proprietà

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

5
Quando non usi le proprietà implementate automaticamente, puoi comunque accedervi in ​​questo modo. cioè l'AIP non riguarda l'accesso dall'esterno, ma la dichiarazione all'interno di una classe.
abatishchev,

4

Tale { get; set; }sintassi si chiama proprietà automatiche, sintassi C # 3.0

È necessario utilizzare Visual C # 2008 / csc v3.5 o successivo per la compilazione. Ma è possibile compilare un output destinato a un minimo di .NET Framework 2.0 (non sono necessari runtime o classi per supportare questa funzionalità).


4

In Visual Studio, se si definisce una proprietà Xin una classe e si desidera utilizzare questa classe solo come tipo, dopo aver creato il progetto verrà visualizzato un avviso che dice "Il campo X non è mai assegnato e avrà sempre il suo valore predefinito valore " .

Con l'aggiunta di un { get; set; }a Xproprietà, non sarà possibile ottenere questo avvertimento.

Inoltre, in Visual Studio 2013 e versioni successive, aggiungendo { get; set; }puoi vedere tutti i riferimenti a quella proprietà.

inserisci qui la descrizione dell'immagine


4

Fondamentalmente è una scorciatoia. Puoi scrivere public string Name { get; set; }come in molti esempi, ma puoi anche scriverlo:

private string _name;

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

Perché è usato? Può essere utilizzato per filtrare l'accesso a una proprietà, ad esempio non si desidera che i nomi includano numeri.

Lasciate che vi faccia un esempio:

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;
        }
    }
}

Ufficialmente si chiama Auto-Implemented Properties e ha la buona abitudine di leggere la ( guida alla programmazione ). Vorrei anche raccomandare tutorial video Proprietà C #: Perché usare "get" e "set" .


2

Ottieni set sono modificatori di accesso alla proprietà. Ottieni legge il campo proprietà. Set imposta il valore della proprietà. Ottieni è come l'accesso in sola lettura. Set è come l'accesso in sola scrittura. Per utilizzare la proprietà come lettura, è necessario utilizzare sia get che set.


1
penso che ottenere set non sono modificatori di accesso, infatti sono accessori. I modificatori di accesso sono come: pubblico, privato, interno ecc.
Rohit Arora,

1

Get viene richiamato quando la proprietà appare sul lato destro (RHS) Il set viene invocato quando la proprietà appare sul lato sinistro (LHS) del simbolo '='

Per una proprietà implementata automaticamente, il campo di supporto funziona dietro la scena e non è visibile.

Esempio:

public string Log { get; set; }

Considerando che per una proprietà non implementata automaticamente il campo di supporto è in anticipo, visibile come variabile con ambito privato.

Esempio:

private string log;

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

Inoltre, vale la pena notare che qui è 'getter' e 'setter' può usare il diverso 'campo di supporto'


Questo non sembra rispondere alla domanda posta.
TylerH,

Fornito suggerimento su quando viene richiamato get & set. Tutte le risposte sopra menzionate danno l'impressione che il campo di supporto per get & set sia lo stesso. Ma non è così. Quindi la mia risposta è molto rilevante per la domanda principale. Spero che tu sia d'accordo con me
Bala,

Per una proprietà generata automaticamente, che è ciò che la domanda pone, non ci possono essere diversi campi di supporto usati per il getter e il setter; c'è solo un campo di supporto. Per una proprietà non auto (di cui non si pone la domanda) potrebbe non esserci nemmeno un campo di supporto concettuale. Inoltre, è possibile scrivere un programma con un getter sul lato sinistro di un operatore di assegnazione e uno con un setter sul lato destro di un operatore di assegnazione. Quindi non solo tutte queste informazioni non rispondono alla domanda posta, ma sono anche tutte sbagliate.
Serve

0

Definire le variabili private

All'interno del costruttore e carica i dati

Ho creato Costante e caricato i dati dalla costante alla classe Elenco selezionato.

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

Una proprietà è simile a un livello che separa la variabile privata dagli altri membri di una classe. Dal mondo esterno sembra che una proprietà sia solo un campo, una proprietà è accessibile tramite .Property

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 è una proprietà. Quello con la freccia è una scorciatoia. Dall'esterno, possiamo accedere a FullName in questo modo:

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

I chiamanti non si preoccupano di come hai implementato FullName. Ma all'interno della classe puoi cambiare FullName come preferisci.

Consulta la documentazione Microsoft per una spiegazione più dettagliata:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.