web-dev-qa-db-fra.com

Setter omis vs setter privé?

Quelle est la différence entre une propriété avec un setter omis et une propriété avec un setter privé?

public string Foo { get; private set; }

contre

public string Foo { get; }
38
Fred

En C # 6, get; seules les propriétés ne peuvent être réglées qu'à partir du constructeur. Partout ailleurs, il est en lecture seule.

Une propriété avec un private set; peut être défini de partout dans cette classe.

53
Patrick Hofman

En dehors de la classe, cela ne changera rien si vous utilisez cette syntaxe:

public string Foo { get; }

Mais vous ne pourrez pas mettre à jour Foo dans la classe, sauf dans le constructeur, pour cela, vous aurez besoin du setter privé:

public string Foo { get; private set; }
10
Thomas Ayoub

La différence est que le code généré produira un champ en lecture seule dans le second cas, et évidemment la propriété n'aura pas de setter.

Faisons un vrai exemple:

public class Test
{
    public Test(string name) { Name = name; }
    public string Name { get; private set; }
}

Le compilateur compilera ceci comme ceci:

public class Test
{
    private string <Name>k__BackingField;
    public Test(string name)
    {
        <Name>k__BackingField = name;
    }
    public string Name
    {
        get { return <Name>k__BackingField; }
        private set { <Name>k__BackingField = value; }
    }
}

Comme vous pouvez le voir, le compilateur a réécrit automatiquement votre code pour avoir un champ de sauvegarde pour la propriété. Le nom du champ sera ce nom cryptique, qui est légal .NET mais pas C #, ce qui signifie que vous ne pouvez jamais écrire de code C # en conflit avec un tel membre généré automatiquement.

Fondamentalement, les propriétés automatiques en C # ne sont que du sucre syntaxique pour une propriété avec un champ de support, la propriété réelle en cours de compilation a toujours un champ de support, vous n'avez tout simplement pas à l'écrire explicitement.

Comme vous pouvez le voir, il a également réécrit automatiquement le constructeur pour écrire directement dans le champ. Notez que cela se fera partout dans cette classe où la propriété est écrite, car il n'y a aucune chance pour qu'un code personnalisé soit de toute façon entre les deux.

Supprimons maintenant le setter de la propriété et voyons ce qui se passe:

public class Test
{
    private readonly string <Name>k__BackingField;
    public Test(string name)
    {
        <Name>k__BackingField = name;
    }
    public string Name
    {
        get { return <Name>k__BackingField; }
    }
}

Notez que le champ est désormais en lecture seule, et encore une fois, le setter a également disparu de la propriété.

C'est donc en fait la meilleure façon de créer des types simples avec des propriétés en lecture seule true, non seulement la propriété elle-même n'est pas accessible en écriture, mais le champ de support est également en lecture seule, ce qui signifie que vous êtes maintenant mieux équipé pour écrire facilement types immuables.

6
Lasse V. Karlsen

Le setter private est - enfin - une méthode de set privé que vous pouvez utiliser uniquement à l'intérieur de votre classe.

Le paramètre omis définit la propriété readonly. Vous ne pouvez donc définir la valeur de cette propriété que dans vos constructeurs ou via une initialisation statique.

4
René Vogt

Une propriété avec un setter omis est en lecture seule partout sauf le constructeur de classe - y compris à l'intérieur de la classe.

Une propriété avec un setter privé est en lecture seule en externe (même pour les sous-classes), mais accessible en écriture en interne.

3
ChrisF