Cette question a été posée dans les commentaires de cette réponse. L'incapacité d'avoir des propriétés en lecture seule a été proposée comme une raison potentielle d'utiliser des champs au lieu de propriétés.
Par exemple:
class Rectangle
{
private readonly int _width;
private readonly int _height;
public Rectangle(int width, int height)
{
_width = width;
_height = height;
}
public int Width { get { return _width; } }
public int Height { get { return _height; } }
}
Mais pourquoi ne pas simplement faire ceci?
public int Width { get; readonly set; }
Édition (clarification): Vous pouvez obtenir cette fonctionnalité dans le premier exemple. Mais pourquoi ne pouvez-vous pas utiliser la forme abrégée de propriété avec implémentation automatique pour faire la même chose? Ce serait également moins désordonné, car vous n'auriez pas à accéder directement aux champs dans votre constructeur; tout accès se ferait à travers la propriété.
Édition (mise à jour): À partir de C# 6.0, les propriétés en lecture seule sont supportées! object MyProp { get; }
Cette propriété peut être définie en ligne (object MyProp { get; } = ...
) ou dans le constructeur, mais nulle part ailleurs (tout comme les champs readonly
).
7 votes
Une meilleure syntaxe serait
public int Width { get; readonly set; }
.0 votes
@Jason : Cela semble effectivement mieux - Je l'ai modifié selon votre version.
3 votes
@Jason: Je ne sais pas, quelque chose à propos du concept d'un "setter en lecture seule" me semble très bizarre. C'est facile à comprendre ici, dans le contexte de cette question, mais je pense que si je le voyais sans prévenir, ça serait un moment de WTF.
0 votes
@Aaronaught : Je suis sûr que vous savez ce que signifie le mot-clé
readonly
, mais juste pour être clair, cela signifie que les affectations directes à une variable marquée avec le modificateurreadonly
ne peuvent se produire qu'au point de déclaration ou dans le constructeur. Ainsi,readonly set
signifierait "cette propriété ne peut être définie que dans le constructeur ou dans un initialiseur d'objet".0 votes
@Jason: En effet, la terminologie est techniquement correcte, c'est juste aussi très déconcertant ; je préférerais que vous puissiez simplement écrire
{ get; }
et que le compilateur vous permette de l'assigner dans le constructeur.0 votes
@Aaronaught : Non, le problème avec cela est que cela ne vous permet pas de communiquer à l'utilisateur que la propriété est
readonly
. Ce n'est pas seulement une question de sémantique (qui est déjà possible dans le langage) ou d'intention, mais de pouvoir communiquer cette sémantique et cette intention à l'utilisateur d'une manière qui est imposée par le compilateur.0 votes
@ Jason: Personnellement, je ne trouve pas l'intention aussi claire.
set
n'est pas un champ qui peut être assigné, c'est une méthode; Je réalise que pour vous, il est évident que les mêmes sémantiques s'appliqueraient, mais cela peut ne pas être évident pour tout le monde. D'autres mots-clés ont des significations différentes selon le contexte (commeusing
). D'un autre côté, une auto-propriété avec seulement unget
devrait être assignée quelque part, donc il est logiquement intuitif pour moi que cela se fasse dans le constructeur. Voilà mon avis; vous n'êtes pas obligé d'être d'accord et de toute façon, cela ne change rien puisque cela ne se produira pas. ;)0 votes
@Aaronaught: Le problème avec cet argument est qu'un appel de méthode
set
ne ressemble pas à un appel de méthode, il ressemble à une affectation de champ, c'est donc raisonnable de s'attendre à ce qu'il se comporte comme un champ. C'est pourquoi certains d'entre nous ont aimé l'idée dereadonly set
. D'un autre côté, l'un des grands avantages des propriétés dans la conception d'interfaces est la possibilité de refacto un auto-property en une propriété complète sans changer l'interface. Un auto-propertyreadonly set
ne pourrait jamais être converti en un non auto-property sans changer l'interface cependant. Cela seul suffit à tuer l'idée pour moi.0 votes
Comment
public readonly int Width { get; }
1 votes
Note : Jon Skeet a spécifiquement mentionné ce point comme quelque chose qu'il voulait dans C# 5.0 dans sa diffusion DDD8.