Quel est le {get; ensemble; } syntaxe en C #?

578

J'apprends ASP.NET MVC et je peux lire des documents en anglais, mais je ne comprends pas vraiment ce qui se passe dans ce code:

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

Qu'est-ce que cela signifie { get; set; }:?

kn3l
la source
4
En général, souvenez-vous que les poseurs rendent votre objet mutable, une mauvaise idée. les getters violent "Dites à un objet quoi faire, ne lui demandez pas d'informations et manipulez-le vous-même". Donc, en général, n'ajoutez pas de setters et de getters par défaut. Vous en aurez souvent besoin, mais vous devriez toujours trouver un réel besoin avant de les ajouter. En particulier, les setters ne devraient presque jamais être utilisés dans le code de production (recherchez l'immuabilité dans la mesure du possible, et lorsque la mutation est nécessaire, vous devez lui demander de muter pour vous, pas de définir une valeur).
Bill K
8
Juste pour ajouter quelque chose ... Si vous ne mettez pas, {get; set;}vous créez un champ mais si vous mettez la, {get; set;}vous créez une propriété . Avoir une propriété peut faciliter certaines choses, surtout lorsque vous travaillez avec Reflection.
Seichi
@Seichi utilisant un get-setter crée également un champ, mais celui-ci est caché, déclaré privé et modifié par les propriétés créées automatiquement; tout cela fait par le compilateur.
Jonathan Ramos
1
les propriétés automatiques ne vont-elles pas à l'encontre du but des champs privés ?
mireazma

Réponses:

568

C'est une soi-disant propriété automatique, et est essentiellement un raccourci pour les éléments suivants (un code similaire sera généré par le compilateur):

private string name;
public string Name
{
    get
    {
        return this.name;
    }
    set
    {
        this.name = value;
    }
}
Klaus Byskov Pedersen
la source
93
Klaus, pouvez-vous expliquer ce qui va se passer avec ce code? Il pourrait bénéficier d'une explication plus approfondie.
TylerH
3
Donc, juste pour être sûr: c'est comme si j'avais surchargé l' =opérateur, mais seulement pour un élément particulier, non?
Hi-Angel
9
Pourquoi avons-nous besoin de la var privée. :-/ la honte.
Oliver Dixon
2
@TylerH La raison de la variable privée est l'encapsulation, le get / set fournit une "porte" pour obtenir ou définir la variable. Bien qu'il existe de nombreuses raisons de ne pas utiliser get / setters car la «porte» peut rompre l'encapsulation de la variable privée. (il ne devrait pas être accessible)
Alexander
4
C'est peut-être évident, mais je tiens à préciser que la sténographie n'est pas littéralement une sténographie pour cela. Autrement dit, aucune variable privée namen'est créée. Si vous avez essayé de référencer cette variable privée dans la classe, elle échouera. Je ne sais pas comment C # le fait, mais il se comporte comme s'il y avait une variable privée sans nom, à laquelle vous ne pouvez pas accéder dans votre code.
Denziloe
432

Donc, si je comprends bien, c'est { get; set; }une "propriété automatique" qui, tout comme @Klaus et @Brandon, est un raccourci pour écrire une propriété avec un "champ de sauvegarde". Donc dans ce cas:

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

Cependant, si vous êtes comme moi - il y a environ une heure - vous ne comprenez pas vraiment ce que sont les propriétés et les accesseurs , et vous n'avez pas non plus la meilleure compréhension de certaines terminologies de base. MSDN est un excellent outil pour apprendre des trucs comme celui-ci, mais il n'est pas toujours facile à comprendre pour les débutants. Je vais donc essayer d'expliquer cela plus en profondeur ici.

getet setsont des accesseurs , ce qui signifie qu'ils peuvent accéder aux données et aux informations dans des champs privés (généralement à partir d'un champ de support ) et le font généralement à partir de propriétés publiques (comme vous pouvez le voir dans l'exemple ci-dessus).

Il est indéniable que la déclaration ci-dessus est assez déroutante, alors allons dans quelques exemples. Disons que ce code fait référence aux genres de musique. Donc, dans la classe Genre, nous allons vouloir différents genres de musique. Disons que nous voulons avoir 3 genres: Hip Hop, Rock et Country. Pour ce faire, nous utiliserions le nom de la classe pour créer de nouvelles instances de cette 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)

Maintenant que nous avons créé les instances de la classe Genre, nous pouvons définir les noms de genre en utilisant la propriété 'Name' qui a été définie ci-dessus.

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

Nous pouvons définir le nom de «g1» sur Hip Hop en écrivant ce qui suit

g1.Name = "Hip Hop";

Ce qui se passe ici est en quelque sorte complexe. Comme je l'ai déjà dit, getet setaccédez à des informations à partir de champs privés auxquels vous ne pourriez pas accéder autrement. getpeut uniquement lire les informations de ce champ privé et les renvoyer. setne peut écrire que des informations dans ce domaine privé. Mais en ayant une propriété avec les deux getet setnous pouvons faire ces deux fonctions. Et en écrivant, g1.Name = "Hip Hop";nous utilisons spécifiquement la setfonction de notre propriété Name

setutilise une variable implicite appelée value. Fondamentalement, cela signifie que chaque fois que vous voyez "valeur" à l'intérieur set, cela fait référence à une variable; la variable "valeur". Lorsque nous écrivons, g1.Name =nous utilisons le =pour passer la valuevariable qui dans ce cas est "Hip Hop". Vous pouvez donc essentiellement y penser comme ceci:

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

Il est important de noter que l'exemple ci-dessus n'est pas réellement écrit dans le code. Il s'agit plutôt d'un code hypothétique qui représente ce qui se passe en arrière-plan.

Alors maintenant que nous avons défini le nom de l'instance g1 de Genre , je crois que nous pouvons obtenir le nom en écrivant

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"

et si nous courions cela, nous aurions "Hip Hop"dans notre console.

Donc, pour les besoins de cette explication, je vais également compléter l'exemple avec des sorties

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

Production:

"Genres: Hip Hop, Rock, Country"
Josie Thompson
la source
18
Personnellement, je voudrais simplement le commenterset{name = value;} // 'value' here is equal to "Hip Hop"
maksymiuk
2
@iLoveUnicorns, il est là pour l' abstraction des données . Le champ de support est ce qui contient les données réelles. La définition de la propriété définit en fait comment les données sont accessibles avec les méthodes getet set. Le lien que j'ai fourni contient une excellente citation de John Guttag en haut de la page. Je recommanderais de lire son livre ou même de suivre ce cours en ligne gratuit
Josie Thompson
2
Peut - on utiliser simplement pas: au public class Genre{public string Name;} lieu de: public class Genre{ public string Name { get; set; }}. Je veux dire, pourquoi avons-nous même besoin de {get; ensemble; }?
user2048204
1
On dirait que ma préoccupation a déjà été reprise. Si vous déclarez de cette façon: "public string Name {get; set;}" et que vous accédez de cette façon: g1.Name = "Hip Hop"; - alors où est l'orientation objet? Je n'ai même pas besoin du soi-disant "champ de sauvegarde". Le domaine de l'accompagnement n'existe même pas, en ce qui me concerne. Parce que je n'accède qu'au domaine public. Et si le domaine public est "public", il n'est pas conforme OO. Revenons tous à COBOL.
Baruch Atta
1
Excellente réponse, mais si nous sommes pédant, «set» est un mutateur, pas un accesseur.
pythlang
100

Ce sont des propriétés automatiques

Fondamentalement, une autre façon d'écrire une propriété avec un champ de sauvegarde.

public class Genre
{
    private string _name;

    public string Name 
    { 
      get => _name;
      set => _name = value;
    }
}
Brandon
la source
7
Qu'est-ce qu'on appelle le "champ de sauvegarde"?
kn3l
4
@stackunderflow: Le champ de sauvegarde est l'endroit où les données sont stockées. (ce qui est retourné lors de l'utilisation getet persisté set). Comme l'armoire à laquelle s'ouvre getet setouvre la porte de.
Grant Thomas
5
@stackunderflow: Dans cette réponse, le champ de support est _name. Dans la propriété automatique, le champ de sauvegarde est masqué.
Justin
36

Voici la manière courte de procéder:

public class Genre
{
    private string _name;

    public string Name
    {
      get => _name;
      set => _name = value;
    }
}
froeschli
la source
33

Il s'agit d'un raccourci pour exposer les membres de données en tant que public afin que vous n'ayez pas besoin de créer explicitement de membres de données privés. C # créera un membre de données privées pour vous.

Vous pouvez simplement rendre vos membres de données publics sans utiliser ce raccourci, mais si vous décidez de modifier l'implémentation du membre de données pour avoir une certaine logique, vous devrez rompre l'interface. Donc, en bref, c'est un raccourci pour créer un code plus flexible.

Kelsey
la source
2
Kelsey - pourriez-vous expliquer comment cette syntaxe rend le code plus "flexible"? Je ne le vois pas. Si vous ajoutiez une "logique" au setter ou au getter, dans le cas de l'éther (avec ou sans données privées), vous briseriez toujours l'interface, telle qu'elle est, et auriez besoin d'un codage.
Baruch Atta
18

Fondamentalement, c'est un raccourci de:

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
Jirson Tavera
la source
5
Cela ne répond pas à la question. L'OP parlait de propriétés.
theB
6
Je connais les propriétés Get and Set, c'est un exemple qui aide à mieux comprendre
Jirson Tavera
10

C'est une propriété implémentée automatiquement pour C #.

Daniel A. White
la source
1
Eh ... Cela signifie-t-il que vous gardez une référence nulle à la chaîne et que vous chargez ensuite sa valeur à partir d'un emplacement standard lors de get; set;son appel?
Aurum Aquila
1
Oui, il reste nullcomme n'importe quelle stringvariable jusqu'àsomeInstanceOfGenere.Name = "someValue"
Daniel A. White
6

Ils sont les accesseurs du nom de la propriété publique.

Vous les utiliseriez pour obtenir / définir la valeur de cette propriété dans une instance de Genre.

TimCodes.NET
la source
6

Il s'agit d'une propriété implémentée automatiquement. Il s'agit essentiellement d'une manière abrégée de créer des propriétés pour une classe en C #, sans avoir à leur définir de variables privées. Ils sont normalement utilisés lorsqu'aucune logique supplémentaire n'est requise lors de l'obtention ou de la définition de la valeur d'une variable.

Vous pouvez en savoir plus sur le Guide de programmation des propriétés implémentées automatiquement de MSDN .

Dusda
la source
6
  • Le modèle get / set fournit une structure qui permet à la logique d'être ajoutée lors de la définition ('set') ou de la récupération ('get') d'une instance de propriété d'une classe instanciée, ce qui peut être utile lorsqu'une logique d'instanciation est requise pour le propriété.

  • Une propriété ne peut avoir qu'un accesseur 'get', ce qui est fait pour rendre cette propriété en lecture seule

  • Lors de l'implémentation d'un modèle get / set, une variable intermédiaire est utilisée comme conteneur dans lequel une valeur peut être placée et une valeur extraite. La variable intermédiaire est généralement précédée d'un trait de soulignement. cette variable intermédiaire est privée afin de garantir qu'elle ne soit accessible que via ses appels get / set. Voir la réponse de Brandon, car sa réponse illustre les conventions de syntaxe les plus couramment utilisées pour implémenter get / set.

Chris Halcrow
la source
5

Cela signifie que si vous créez une variable de type Genre, vous pourrez accéder à la variable en tant que propriété

Genre oG = new Genre();
oG.Name = "Test";
David Brunelle
la source
5
Lorsque vous n'utilisez pas de propriétés implémentées automatiquement, vous pouvez toujours y accéder de cette manière. ie AIP ne concerne pas l'accès depuis l'extérieur, mais la déclaration à l'intérieur d'une classe.
abatishchev
4

Cette { get; set; }syntaxe est appelée propriétés automatiques, syntaxe C # 3.0

Vous devez utiliser Visual C # 2008 / csc v3.5 ou supérieur pour compiler. Mais vous pouvez compiler une sortie qui cible aussi bas que .NET Framework 2.0 (aucun runtime ou classe requis pour prendre en charge cette fonctionnalité).

linquize
la source
4

Dans Visual Studio, si vous définissez une propriété Xdans une classe et que vous souhaitez utiliser cette classe uniquement en tant que type, après la génération de votre projet, vous obtiendrez un avertissement indiquant que «le champ X n'est jamais affecté et aura toujours sa valeur par défaut valeur" .

En ajoutant un { get; set; }àX la propriété, vous ne serez pas cet avertissement.

De plus, dans Visual Studio 2013 et les versions supérieures, en ajoutant, { get; set; }vous pouvez voir toutes les références à cette propriété.

entrez la description de l'image ici

Omid Ebrahimi
la source
4

C'est essentiellement un raccourci. Vous pouvez écrire public string Name { get; set; }comme dans de nombreux exemples, mais vous pouvez également l'écrire:

private string _name;

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

Pourquoi est-il utilisé? Il peut être utilisé pour filtrer l'accès à une propriété, par exemple, vous ne voulez pas que les noms incluent des nombres.

Laisse moi te donner un exemple:

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

Officiellement, il s'appelle Propriétés Auto-Implémentées et sa bonne habitude de lire le ( guide de programmation ). Je recommanderais également le didacticiel vidéo Propriétés C #: Pourquoi utiliser "get" et "set" .

Randel
la source
2

Get set sont des modificateurs d'accès à la propriété. Get lit le champ de propriété. Set définit la valeur de la propriété. Obtenir, c'est comme un accès en lecture seule. L'ensemble est comme l'accès en écriture seule. Pour utiliser la propriété en lecture-écriture, get et set doivent être utilisés.

Ashraf Abusada
la source
1
je pense que get set ne sont pas des modificateurs d'accès, en fait ce sont des accesseurs. Les modificateurs d'accès sont comme: public, privé, interne, etc.
Rohit Arora
1

Get est invoqué lorsque la propriété apparaît sur le côté droit (RHS) Set est invoqué lorsque la propriété apparaît sur le côté gauche (LHS) du symbole '='

Pour une propriété implémentée automatiquement, le champ de support fonctionne derrière la scène et n'est pas visible.

Exemple:

public string Log { get; set; }

Alors que pour une propriété non implémentée automatiquement, le champ de sauvegarde est initial, visible en tant que variable de portée privée.

Exemple:

private string log;

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

En outre, il convient de noter ici que le «getter» et le «setter» peuvent utiliser les différents «champs de support»

Bala
la source
Cela ne semble pas répondre à la question posée.
TylerH
Indication fournie lorsque l'invocation de get & set est invoquée. Toutes les réponses mentionnées ci-dessus donnent l'impression que le champ de support pour get & set est le même. Mais ce n'est pas le cas. Ma réponse est donc très pertinente par rapport à la question principale. J'espère que vous êtes d'accord avec moi.
Bala
Pour une propriété générée automatiquement, sur laquelle porte la question, il ne peut pas y avoir différents champs de support utilisés pour le getter et le setter; il n'y a qu'un seul champ de support. Pour une propriété non automatique (sur laquelle la question ne pose pas de question), il peut même ne pas y avoir de champ conceptuel du tout. En outre, vous pouvez écrire un programme avec un getter sur le côté gauche d'un opérateur d'affectation et un avec un setter sur le côté droit d'un opérateur d'affectation. Donc, non seulement toutes ces informations ne répondent pas à la question posée, mais elles sont également toutes fausses.
Servy
0

Définissez les variables privées

À l'intérieur du constructeur et chargez les données

J'ai créé Constant et charge les données de la constante à la classe Liste sélectionnée.

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

}
Hari Lakkakula
la source
0

Une propriété est comme une couche qui sépare la variable privée des autres membres d'une classe. Du monde extérieur, on a l'impression qu'une propriété n'est qu'un champ, une propriété est accessible en utilisant .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 est une propriété. Celui avec une flèche est un raccourci. Du monde extérieur, nous pouvons accéder à FullName comme ceci:

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

Les appelants ne se soucient pas de la façon dont vous avez implémenté le FullName. Mais à l'intérieur de la classe, vous pouvez modifier FullName comme vous le souhaitez.

Consultez la documentation Microsoft pour une explication plus détaillée:

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

MING WU
la source