Une propriété n'est rien de plus qu'une encapsulation d'un Get
méthode et/ou un Set
méthode. Le CLR a métadonnées qui indique que les méthodes particulières doivent être considérés comme étant une des propriétés, sens compilateurs devrait permettre à certaines constructions qui ne permettrait pas avec des méthodes. Par exemple, si X
est une propriété en lecture-écriture de l' Foo
, un compilateur va traduire Foo.X += 5
en Foo.SET_X_METHOD(Foo.GET_X_METHOD() + 5)
(si les méthodes sont nommés différemment, et ne sont généralement pas accessibles par leur nom).
Bien qu'un autoproperty met en œuvre une paire de méthodes get/set dont l'accès à une zone privée de manière à se comporter plus ou moins comme un champ, du point de vue de n'importe quel code à l'extérieur de la propriété, un autoproperty est une paire de méthodes get/set, tout comme toute autre propriété. Par conséquent, une instruction comme celle - Foo.X = 5;
est traduit Foo.SET_X_METHOD(5)
. Depuis le compilateur C# ne voit que comme un appel de méthode, et puisque les méthodes ne comprennent pas toutes les métadonnées pour indiquer que les champs de lecture ou d'écriture, le compilateur va interdire l'appel de la méthode, à moins qu'il connaît tous les domaines de l' Foo
a été écrit.
Personnellement, mon conseil serait d'éviter l'utilisation de autoproperties avec les types de structure. Autoproperties faire du sens avec les classes, puisqu'il est possible pour des propriétés de la classe de fonctions de support comme les notifications de mise à jour. Même si les premières versions d'une classe ne supportent pas les notifications de mise à jour, d'avoir ces versions utilisent un autoproperty plutôt qu'un champ de dire que les futures versions pouvez ajouter de mise à jour-les fonctions de notification sans exiger les consommateurs de la classe à être retravaillé. Toutefois, les Structures ne peuvent pas de manière significative en charge la plupart des types de caractéristiques que l'on pourrait le souhaiter pour ajouter un champ des propriétés similaires.
En outre, les différences de performances entre les champs et les propriétés est beaucoup plus grande avec de grandes structures que c'est avec des types de classe. En effet, une grande partie de la recommandation d'éviter les grandes structures est une conséquence de cette différence. Les grandes structures peuvent effectivement être très efficace, si l'on évite les copier inutilement. Même si l'on avait un énorme structure HexDecet<HexDecet<HexDecet<Integer>>>
où HexDecet<T>
contenus exposés champs F0
..F15
de type T
, une instruction comme celle - Foo = MyThing.F3.F6.F9;
serait tout simplement besoin de la lecture d'un entier compris entre MyThing
et de le stocker dans Foo
, même si MyThing
serait énorme par struct normes (4096 entiers occupant 16K). En outre, on pourrait mettre à jour cet élément très facilement, par exemple, MyThing.F3.F6.F9 += 26;
. En revanche, si F0
..F15
ont été auto-propriétés, l'énoncé Foo = MyThing.F3.F6.F9
nécessiterait la copie de 1K de données à partir d' MyThing.F3
temporaire (appelons - temp1
, 64 octets de données à partir d' temp1.F6
de temp2
) avant de finalement se déplacer à la lecture de 4 octets de données à partir d' temp2.F9
. Ick. Pire, en essayant d'ajouter 26 de la valeur en MyThing.F3.F6.F9
aurait besoin de quelque chose comme var t1 = MyThing.F3; var t2 = t1.F6; t2.F9 += 26; t1.F6 = f2; MyThing.F3 = t1;
.
De nombreuses plaintes de longue date au sujet de "mutable types de structure" sont en réalité des plaintes au sujet de la structure avec des types de propriétés en lecture/écriture. Il suffit de remplacer les propriétés de champs et les problèmes disparaissent.
PS: Il y a des moments, il peut être utile de disposer d'une structure dont les propriétés accéder à une classe d'objets à laquelle elle détient une référence. Par exemple, il serait bien d'avoir une version de l' ArraySegment<T>
de la classe qui lui permettait de dire Var foo[] = new int[100]; Var MyArrSeg = New ArraySegment<int>(foo, 25, 25); MyArrSeg[6] += 9;
, et la dernière déclaration ajouter de neuf à l'élément (25+6) foo
. Dans les anciennes versions de C# on pourrait le faire. Malheureusement, l'utilisation fréquente de autoproperties dans le Cadre où les champs aurait été plus approprié entraîné des plaintes concernant le compilateur permettant de propriété organismes de normalisation pour être appelé inutilement sur les structures; par conséquent, l'appel à tout le setter de la propriété en lecture seule structure est désormais interdite, que ce soit ou non la propriété setter serait effectivement de modifier tous les champs de la structure. Si les gens avaient tout simplement s'abstenir de faire des structures mutables via des accesseurs de propriété (prise de champs directement accessible lors de la mutabilité était approprié) les compilateurs n'auraient jamais eu à mettre en œuvre du fait de cette restriction.