58 votes

Propriétés en écriture seule, à quoi ça sert?

Je comprends pourquoi vous souhaitez utiliser une propriété en lecture seule à l'aide de la syntaxe suivante:

private int _MyInt;
public int MyInt
{
  get { return _MyInt; }
}

Cet exemple n'est probablement pas le meilleur parce que je pense que les propriétés en lecture seule vraiment briller en conjonction avec un readonly variable, mais c'est à côté de la question. Ce que je ne comprends pas, c'est pourquoi l'utilisation d'une propriété en écriture seule à l'aide de la syntaxe suivante:

private int _MyInt;
public int MyInt
{
  set { _MyInt = value; }
}

C'est la façon dont les propriétés en lecture seule sont décrits dans de nombreux livres et des tutoriels. Si vous définissez la variable, vous pourriez théoriquement le lire sur certains point, au moins en interne à la classe, mais de le lire, même en interne dans la classe que vous le feriez par accesssing _MyInt qui je me sens contraire à l'esprit de l'encapsulation des propriétés essayer d'appliquer. Au lieu de cela, pourquoi ne pas vous suffit d'utiliser la pleine puissance de la propriété avec accès différents modifie pour y accéder en tant que tel:

private int _MyInt;
public int MyInt
{
  set { _MyInt = value; }
  private get { return _MyInt; }
}

Ce qui bien sûr peut-être simplement écrit

public int MyInt { set; private get; }

Vous obtenez toujours l'encapsulation, mais de restreindre d'autres classes de l'accès, de sorte que son toujours en écriture uniquement à l'extérieur des classes.

Sauf si il ya un cas où vous honnêtement souhaitez affecter à une variable, mais jamais réellement accès, auquel cas je serais certainement curieux de savoir quand cette nécessité surviennent.

73voto

Andrew Hare Points 159332

Je n'ai jamais trouvé de valable de cas d'utilisation pour une propriété en écriture seule. Honnêtement, s'il y a un cas d'utilisation pour une propriété en écriture seule, je pense qu'il est sûr de dire que la solution est mal conçu.

Si vous avez besoin d' "écriture seule" sémantique que vous devez utiliser une méthode. Par exemple, un autre utilisateur a trouvé un exemple d'un objet utilisateur qui utilise une propriété en écriture seule pour définir un mot de passe. C'est une mauvaise conception:

class User
{
    public string Password
    {
        set { /* password encryption here */ }
    }
}

Ugh. C'est beaucoup mieux:

class User
{
    public void SetPassword(string password)
    {
        /* password encryption here */
    }
}

Voir, une propriété de lecture/écriture est un ensemble de méthodes qui sont conçus pour se faire passer pour un champ. Ils regardent et se sentent comme un champ. C'est pour cette raison qu'une propriété en lecture seule a un sens, car nous sommes habitués à avoir des champs et des variables que l'on peut lire mais pas les modifier. Cependant il n'y a pas de champ correspondant à la variable ou de construire qui est accessible en écriture mais pas lisible.

C'est pourquoi je crois que la création d'une API qui emploie des propriétés en écriture seule est une mauvaise pratique. Il s'exécute à contre-intuitif à ce que je crois est l'objectif principal de la propriété de syntaxe en C#.

Edit: Plus de la philosophie... je crois que les classes ont un objectif fonctionnel: ils fournissent un conteneur pour les données relatives à la tenue et de manipulation. Prendre notre User classe par exemple - que cette classe va contenir tous les éléments d'information qui se rapportent à un utilisateur dans le système. Nous recueillons tous ces éléments de données et de leur donner un seul nom d'utilisateur. De cette façon nous utilisons les classes pour créer des abstractions. User est une abstraction qui nous permet de raisonner sur tous les éléments de données qui composent un utilisateur (mot de passe, nom, prénom, date de naissance, etc.).

Il y a maintenant bien des abstractions et il y a de mauvaises abstractions. Je crois que l'écriture seule propriétés sont mauvais abstractions que vous laissez quelqu'un pour les données d'entrée et de ne pas le lire. Pourquoi voulez-vous interdire cela? Probablement parce que l'information qui a été adoptée en a été transformé d'une manière qui le rend illisible pour le passant.

Cela signifie donc qu'une propriété en écriture seule , par définition, doit créer les effets secondaires que l'appelant ne peut pas voir (parce que si ils pouvaient les voir, alors il n'y aurait aucune raison de faire de la propriété en écriture seule). Le meilleur de construire dans le langage C# pour la définition de la valeur avec des effets secondaires est la méthode.

Je vous recommande fortement de ne pas utiliser de propriétés en écriture seule, parce que les consommateurs de votre API trouverez déroutant et frustrant. Même si vous trouvez un valide de cas d'utilisation de cette syntaxe, il n'a pas à justifier de son utilisation.


Edit: Voici des recommandations officielles à partir .Net Cadre des lignes Directrices de Conception pour le Développement de Bibliothèques de Classe -> Membre Des Lignes Directrices De Conception-> Propriété De Conception

Ne fournissent pas de set-seules les propriétés.

Si la propriété de lecture ne peut pas être fourni, l'utilisation d'une méthode à mettre en œuvre la fonctionnalité de la place. Le nom de la méthode doit commencer par Définir suivie par ce qui aurait été le nom de la propriété...

16voto

Thomas Points 63635

Question interessante.

Après quelques recherches sur Google, c'est tout ce que je pouvais trouver: une propriété en écriture ne peut être utilisé pour définir un mot de passe sur un User objet. Étant donné que les mots de passe sont généralement stockés sous forme hachée, il n’ya pas (et ne devrait pas être) un moyen de récupérer un mot de passe une fois qu’il a été défini.

11voto

neontapir Points 2692

Une utilisation pour une propriété en écriture seule est de soutenir le setter de l'injection de dépendance.

Disons que j'ai eu une classe:

public class WhizbangService {
    public WhizbangProvider Provider { set; private get; }
}

Le WhizbangProvider n'est pas destiné à être consulté par le monde extérieur. Je ne voudrais jamais d'interagir avec d' service.Provider, c'est trop complexe. J'ai besoin d'une classe comme WhizbangService d'agir comme une façade. Pourtant, avec le setter, je peux faire quelque chose comme ceci:

service.Provider = new FireworksShow();
service.Start();

Et le service démarre un feu d'artifice. Ou peut-être vous préférez voir de l'eau et un spectacle de lumière:

service.Stop();
service.Provider = new FountainDisplay(new StringOfLights(), 20, UnitOfTime.Seconds);
service.Start();

Et ainsi de suite....

6voto

Steve Danner Points 11604

Je peux voir un cas courant, si vous vouliez seulement qu'un appelant puisse obtenir une version transformée de votre propriété. Par exemple:

 public int MyInt { set; }
public string MyIntAsString 
{ 
   get { return this.MyInt.ToString(); } 
}
 

De toute évidence, ce n'est pas un exemple réel, mais vous obtenez l'image.

EDIT :

Après avoir lu l'exemple d'utilisation de Thomas, un scénario de type "transformation" pourrait consister à récupérer une version chiffrée de la propriété en écriture seule:

 private string password;

public string ClearPassword { set { this.password = value; }
public string EncryptedPassword
{
   get { return Encrypt(password); }
}
 

2voto

Wes P Points 3153

Des sources que j'ai lues ont suggéré que si vous aviez honnêtement une situation dans laquelle vous venez de créer une propriété en écriture seule, vous devriez probablement envisager de la transformer en une méthode. Et je suis généralement d'accord.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X