70 votes

C# paramètre de propriété et ref, pourquoi sans sucre ?

Je viens de tomber sur ce message d'erreur tout en travaillant en C#

Une propriété ou d'indexation ne peut être adopté comme une sortie ou paramètre de référence

J'ai connu ce qui a causé cela et n'a la solution rapide de créer une variable locale de type approprié, l'appel de la fonction avec comme l' out/ref paramètre et en l'affectant de retour à la propriété:

RefFn(ref obj.prop);

se transforme en

{
    var t = obj.prop;
    RefFn(ref t);
    obj.prop = t;
}

Clairement, ce serait un échec si la propriété ne prend pas en charge get et set dans le contexte actuel.

Pourquoi ne pas C# juste faire ça pour moi?


Le seul cas où, je pense, d'où cela peut causer des problèmes sont les suivants:

  • filetage
  • exceptions

Pour le filetage de cette transformation affecte lorsque les écritures arriver (après l'appel de la fonction, par opposition à l'appel de la fonction), mais je soupçonne plutôt de n'importe quel code qui compte sur qui serait peu de sympathie quand il se casse.

Pour les exceptions, le problème serait à ce qui se passe si la fonction attribue à l'un de plusieurs ref paramètres de jette? Toute solution triviale entraînerait tous ou aucun des paramètres assignés à quand certains et certaines ne devrait pas être. Encore une fois je ne pense pas que ce serait en faveur de l'utilisation de la langue.


Note: j'ai compris la mécanique de pourquoi ce message d'erreur est généré. Ce que je cherche est la raison pour laquelle C# n'a pas automatiquement la mise en oeuvre de la solution triviale.

32voto

David Morton Points 10519

Parce que vous êtes de passage le résultat de l'indexation, qui est en réalité le résultat d'un appel de méthode. Il n'y a aucune garantie que l'indexation de la propriété dispose également d'un setter, et en passant par ref conduirait à une fausse sécurité sur le développeur de la partie quand il pense que sa propriété va être créé sans l'incubateur d'être appelé.

Sur un plan plus technique, ref et passe l'adresse mémoire de l'objet passé en eux, et de définir une propriété, vous devez appeler le setter, donc il n'y a aucune garantie que la propriété pourrait être réellement changé, surtout quand le type de propriété est immuable. ref et out n'est pas seulement de définir la valeur sur le retour de la méthode, qu'ils passent à la mémoire réelle référence à l'objet lui-même.

17voto

user7116 Points 39829

Les propriétés sont rien de plus que du sucre syntaxique sur le Java style getX/setX méthodes. Il ne fait pas beaucoup de sens pour " ref " sur une méthode. Dans votre exemple, il serait logique car vos propriétés sont simplement déraciner les champs. Les propriétés n'ont pas à être juste sur les talons, partant, le cadre ne peut pas permettre de " ref " sur Propriétés.

EDIT: eh Bien, la réponse est simple, le simple fait qu'un Bien getter ou un setter pourrait inclure beaucoup plus que juste un champ en lecture/écriture le rend indésirable, pour ne pas mentionner imprévue, pour permettre le tri de sucre que vous proposez. Ce n'est pas à dire que je n'ai pas eu besoin de cette fonctionnalité avant, c'est juste que je comprends pourquoi ils ne veulent pas fournir.

11voto

Marc Gravell Points 482669

Juste pour info, C# 4.0 va avoir quelque chose comme ce sucre, mais uniquement lors d’un appel des méthodes interop - en partie en raison de la propension pure de `` dans ce scénario. Je n’ai pas testé beaucoup (dans la version CTP) ; Il faudra voir comment il casseroles...

9voto

Brian Rasmussen Points 68853

Vous pouvez utiliser les champs avec / , mais pas de propriétés. La raison est que les propriétés sont vraiment juste un raccourci syntaxe pour les méthodes spéciales. Le compilateur traduit effectivement get / set des propriétés correspondant à et méthodes telles que le CLR n’a aucun soutien immédiat pour les propriétés.

6voto

Mark Rendle Points 4592

Il ne serait pas thread-safe ; Si deux threads simultanément créent leurs propres copies de la valeur de la propriété et les transmettre aux fonctions comme paramètres ref, seulement un d’eux finit par revenir dans la propriété.

PropertyX finit par 1, alors qu’un champ ou variable locale serait 2.

Cet exemple de code souligne également les difficultés introduites par des choses comme les méthodes anonymes lorsque vous demandez au compilateur de faire des trucs sucrés.

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