web-dev-qa-db-fra.com

Propriété automatisée avec getter uniquement, peut être définie, pourquoi?

J'ai créé une propriété automatisée:

public int Foo { get; } 

Ceci est seulement getter. Mais quand je construis un constructeur, je peux changer la valeur:

public MyClass(string name)
{
    Foo = 5;
}

Pourquoi est-ce possible, même s'il s'agit d'un get-only?

83
Noam B.

Il s'agit d'une nouvelle fonctionnalité de C # 6, "Propriétés automatiques réservée aux lecteurs-", également connue sous le nom "Initialiseurs de propriétés automatiques pour les propriétés en lecture seule", comme indiqué dans ce article du magazine MSDN 'C #: Le nouveau et le amélioré C # 6.0 'de Mark Michaelis et dans la spécification de langage C # 6. .

Le setter du champ en lecture seule est uniquement accessible dans le constructeur. Dans tous les autres scénarios, le champ est toujours en lecture seule et se comporte comme auparavant.

Il s'agit d'une syntaxe pratique visant à réduire la quantité de code que vous devez taper et à supprimer le besoin de déclarer explicitement une variable de niveau de module privé pour contenir la valeur.

Cette fonctionnalité était considérée comme aussi importante que, depuis l'introduction des propriétés implémentées automatiquement en C # 3, les propriétés mutables (celles avec getter et setter) étaient devenues plus rapides à écrire que celles immuables (celles avec seulement getter), ce qui signifiait être tenté d'utiliser des propriétés mutables pour éviter d'avoir à taper le code d'un champ de sauvegarde généralement requis pour les propriétés en lecture seule. Il existe une discussion plus détaillée sur les propriétés implémentées automatiquement dans le section pertinente du Guide de programmation Microsoft C # .

Ce billet de blog, '# 1 207 - C # 6.0 - Initialiseurs de propriété automatique pour les propriétés en lecture seule' par Sean Sexton A une bonne explication et des exemples, comme suit:

Avant C # 6.0, si vous vouliez une propriété en lecture seule (immuable), vous utiliseriez généralement un champ de sauvegarde en lecture seule initialisé dans le constructeur, comme indiqué ci-dessous.

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

    // DogCreationTime is immutable
    private readonly DateTime creTime;
    public DateTime DogCreationTime 
    {
        get { return creTime; }
    }

    public Dog(string name)
    {
        Name = name;
        creTime = DateTime.Now;
    }
}

En C # 6.0, vous pouvez utiliser des propriétés implémentées automatiquement pour implémenter une propriété en lecture seule. Vous faites cela en utilisant un initialiseur de propriété automatique. Le résultat est beaucoup plus net que l'exemple ci-dessus, dans lequel nous devions déclarer explicitement un champ de support.

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

    // DogCreationTime is immutable
    public DateTime DogCreationTime { get; } = DateTime.Now;

    public Dog(string name)
    {
        Name = name;
    }
}

Plus de détails peuvent également être trouvés dans le repo de Roslyn sur GitHub :

Les propriétés automatiques peuvent maintenant être déclarées sans setter.

Le champ de support d'une propriété auto uniquement-getter est implicitement déclaré en lecture seule (bien que cela ne soit important que pour des raisons de réflexion). Il peut être initialisé via un initialiseur sur la propriété, comme dans l'exemple ci-dessus. De plus, une propriété uniquement en lecture peut être affectée dans le corps du constructeur du type déclarant, ce qui entraîne l'affectation directe de la valeur au champ sous-jacent:

Il s'agit d'exprimer les types de manière plus concise, mais notez que cela supprime également une différence importante dans le langage entre les types mutable et immuable: les propriétés automatiques étaient un raccourci disponible uniquement si vous vouliez rendre votre classe mutable, et donc la tentation de la valeur par défaut. c'était super. Maintenant, avec les propriétés automatiques de getter-seulement, le terrain de jeu a été nivelé entre mutable et immuable.

et dans le brouillon de spécification de langage C # 6. (NB: la spécification de langage est définitive en ce qui concerne Microsoft, mais elle est doit encore être approuvée comme norme EMCA/ISO , d'où le "brouillon"):

Propriétés automatiquement implémentées

Une propriété automatiquement mise en œuvre (ou auto-property en abrégé) est une propriété non-abstraite non abstraite dotée de corps d'accesseurs uniquement par des points-virgules. Les propriétés automatiques doivent avoir un accesseur get et peuvent éventuellement avoir un accesseur set.

Lorsqu'une propriété est spécifiée en tant que propriété implémentée automatiquement, un champ de support masqué est automatiquement disponible pour la propriété et les accesseurs sont implémentés pour lire et écrire dans ce champ de support. Si la propriété automatique n'a aucun accesseur défini, le champ de sauvegarde est considéré en lecture seule (champs en lecture seule). Tout comme un champ en lecture seule, une propriété automatique de lecture uniquement peut également être affectée dans le corps d'un constructeur de la classe englobante. Une telle affectation affecte directement le champ en lecture seule de la propriété.

Une propriété automatique peut éventuellement avoir un property_initializer, qui est appliqué directement au champ de support en tant que variable_initializer (initialiseurs de variable).

113
tomRedox

C'est ne nouvelle fonctionnalité de C # 6 qui vous permet de créer des propriétés en lecture seule et d'initialiser leurs valeurs à partir du constructeur (ou inline lorsque vous les déclarez).

Si vous essayez de changer la valeur de cette propriété en dehors du constructeur, cela vous donnera une erreur de compilation.

Il est en lecture seule en ce sens qu'une fois que vous avez initialisé sa valeur (en ligne ou à l'intérieur du constructeur), vous ne pouvez pas modifier sa valeur.

24
Yacoub Massad

S'il n'était pas possible d'initialiser la propriété en lecture seule à partir du constructeur (ou d'un initialiseur à propriété automatique), elle serait alors inutile, car elle renverrait toujours la valeur par défaut pour son type (0 pour les valeurs numériques, null pour les types de référence ) La même sémantique est appliquée aux champs en lecture seule dans toutes les versions C #.

Pour définir une véritable propriété exclusivement getter (qui ne peut pas être initialisée à partir du constructeur), vous devez spécifier ce qu'elle retourne dans la définition:

public int Foo { get { return 5; } }

Ou, de manière plus concise, en C # 6:

public int Foo => 5;
16
Douglas

“propriétés implémentées automatiquement en lecture seule”

Tout d'abord, je tiens à préciser que la propriété comme

public string FirstName { get; }

Est connu sous le nom de "propriétés implémentées automatiquement en lecture seule"

Pour vérifier cela, vous pouvez exécuter et vérifier le code ci-dessus avec Visual Studio. Si vous modifiez la version linguistique de C # 6.0 à C # 5.0, le compilateur lève l'exception suivante La fonctionnalité 'propriétés implémentées automatiquement en lecture seule' n'est pas disponible en C # 5. Veuillez utiliser la version 6 ou supérieure du langage.

changer la version du langage C # visitez ici

J'en viens maintenant à votre deuxième question

"Ce n'est que pour les getter. Mais quand je construis un constructeur, je peux changer la valeur ”

Microsoft introduit les "propriétés implémentées automatiquement en lecture seule" sur la logique de lecture seule. Comme nous le savons, le mot clé "readonly" est disponible à partir de C # 1.0. nous utilisons le mot clé "readonly" comme modificateur sur un champ et ce champ peut être affecté de la manière suivante: 2 façons soit au moment de la déclaration ou dans un constructeur de la même classe.

De la même manière, la valeur de "propriétés implémentées automatiquement en lecture seule" peut être affectée de 2 manières

Way1 (au moment de la déclaration):

public string FirstName { get; } = "Banketeshvar";

Way2 (dans un constructeur de la même classe)

Person()
{
 FirstName  = "Banketeshvar";
}

Purely ReadOnly Property

Si vous recherchez une propriété purement en lecture seule, optez pour cette option.

public string FullName => "Manish Sharma";

à présent, vous ne pouvez pas attribuer la valeur de la propriété "FullName" à partir du constructeur. Si vous essayez de faire cela, il lève les exceptions suivantes

“La propriété ou l'indexeur 'Person.FullName' ne peut pas être affecté - il est en lecture seule"

5

La fonctionnalité de propriété automatique a été ajoutée à la langue lors de la publication de C # 3.0. Il vous permet de définir une propriété sans aucun champ de sauvegarde. Toutefois, vous devez toujours utiliser le constructeur pour initialiser ces propriétés automatiques à une valeur autre que celle par défaut. C # 6.0 introduit une nouvelle fonctionnalité appelée initialiseur automatique de propriété qui vous permet d’initialiser ces propriétés sans constructeur, comme ci-dessous:

Auparavant, un constructeur est requis si vous souhaitez créer des objets à l'aide d'une propriété automatique et initialiser une propriété automatique sur une valeur autre que celle par défaut, comme ci-dessous:

public class MyClass
{
    public int Foo { get; }

    public Foo(int foo)
    {
        Foo = foo;
    }
}

Désormais, dans C # 6.0, la possibilité d'utiliser un initialiseur avec la propriété auto signifie qu'aucun code constructeur explicite n'est requis.

public string Foo { get; } = "SomeString";

public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };

Vous pouvez trouver plus d'informations à ce sujet ici

4
Rahul Nikate

Une variable déclarée readonly peut être écrite dans un constructeur, mais dans les langages respectant l'attribut, elle ne peut pas être modifiée après le retour du constructeur. Ce qualificatif a été fourni en tant que fonctionnalité de langage car il est souvent nécessaire pour les champs dont les valeurs varient en fonction des paramètres du constructeur (elles ne peuvent donc pas être initialisées avant le démarrage du constructeur), mais ne doivent pas être modifiées après le retour des constructeurs. utilisable uniquement pour les variables exposées sous forme de champs. La sémantique de readonly- des champs qualifiés aurait dans de nombreux cas été parfaite pour les membres publics, sauf qu'il est souvent préférable que les classes exposent les membres, même immuables, sous forme de propriétés plutôt que de champs.

Tout comme il existe des propriétés automatiques en lecture-écriture permettant aux classes d'exposer des propriétés mutables aussi facilement que des champs ordinaires, des propriétés automatiques en lecture seule existent pour permettre aux classes d'exposer des propriétés immuables aussi facilement que des champs qualifiés readonly. Tout comme readonly-, des champs qualifiés peuvent être écrits dans un constructeur, il en va de même avec les propriétés get-only.

1
supercat