J'ai quelques questions sur le code suivant: Mes questions sont les suivantes: p> Pour essayer de trouver moi-même, j'ai inspecté l'IL produite par le code ci-dessus, et voici l'IL pour le Je soupçonne l'appel à la méthode virtuelle là-bas, sur La raison pour laquelle je demande, c'est qu'il y a un moment, probablement 1 à 2 ans, j'ai vu en ligne une "optimisation" de l'utilisation de la déclaration utilisée. Le cas était où l'instruction utilisée a été utilisée comme syntaxe pour une serrure de temps courte sur un objet, où la serrure a été acquise dans le procédé et une structure a été renvoyée, qui, lorsqu'elle est éliminée, libérerait la serrure, le code comme celui-ci. : p> et le commentaire était-ce que, en modifiant le type de retour de la méthode code> LockTheObject code> de Mais je me demande si cela est vrai, sinon vrai. P> Quelqu'un peut-il me dire dans la bonne direction? Si, afin de voir l'opération de la boîte, je devrai inspecter le code d'assemblage d'exécution, montrez-moi s'il vous plaît un exemple de quoi rechercher, je suis bien versé dans le code de l'assemblage afin que ce n'est pas un problème, mais rien n'a sauté chez moi quand j'ai regardé cela non plus. p> p>
STRIT code> STRIT, renvoyée à partir de
Test () Code> Boîte de la structure ou non? Li>
principal (...) code> méthode: p> < Pré> xxx pré>
l_0010 code> introduira une opération de boxe, mais l'instruction code> code> n'est pas ici. . P>
Idisposable code> à la structure réelle utilisé, la boxe a été évitée. P>
3 Réponses :
Il apparaît comme si tout type de valeur qui est placé dans un Pour plus d'informations, veuillez vous reporter à Utilisation de la déclaration et de la valeur jetable : p>
Il y a un moment, Ian Griffiths a écrit à propos de
une amélioration de sa classe Timedlock
dans lequel il l'a changé d'une classe à
une structure. Ce changement a abouti à un
Type de valeur qui implémente
Idisposable. J'ai eu une question harcelle
à l'arrière de mon esprit à l'époque
que j'ai vite oublié. Les
question est ne serait pas des cas de cette
Tapez Get Boxed lorsque vous appelez disposer? P>
blockQuote>
Et aussi oh non! Pas le timedlock à nouveau! : p>
John Sands souligne une faille dans le
code que j'ai montré dans un blog récent pour
en utilisant des délits sur les serrures sans
abandonner la plus grande partie de la commodité de
C # 'S à l'aide de la déclaration code> ne sera pas en boîte. Cela semble être une optimisation C # car la boxe est uniquement omise lorsqu'un type de valeur implémente
Idisposable code> est dans un
à l'aide de la déclaration code>, non dans aucun autre contexte. P>
LOCK CODE> Mot clé. P>
blockQuote>
L'interaction entre contrainte et callvirt était ce que je cherchais, merci!
Méthodes d'instance sur un type de valeur Prenez un paramètre code> code> comme premier argument similaire à la manière dont les méthodes d'instance sur les types de référence font. Cependant, le paramètre dans ce cas est un pointeur géré sur les données de l'objet, pas une référence à un objet en boîte. Vous pourriez le trouver dans la mémoire comme ceci: Méthodes d'instance sur un Type de valorisation Attendez-vous au pointeur géré sur les données spécifiquement em> la boxe des objets n'est pas requise. Comme vous le voyez ci-dessus, l'opcode ¹ Nous allons aller de l'avant et ignorer données code> est la même dans ces deux cas¹. P>
contraint code> est utilisé avant l'appel. Il indique à l'exécution que les instructions suivantes code> CallVirt CODE> reçoivent un pointeur géré sur un
consoleApplication2.Disposable code> struct au lieu de la référence d'objet qu'il reçoit normalement. Ce faisant, le JIT peut résoudre la surcharge scellée de
Disposer () code> implémentée par la structure et l'appelez directement sans la boxe de l'objet. Sans le préfixe code> Contraind CODE>, l'objet transmis à l'instruction code> CallVirt code> devrait être une référence d'objet, car la procédure de résolution dynamique de l'appel virtuel standard est basée sur le fait que le GC / L'en-tête d'objet est toujours em> dans l'emplacement prévu - et oui, cela obligerait la boxe pour des types de valeur. P>
nullable
Ceci est un duplicata de Si ma structure implémente Idisposable, elle sera encadrée lorsqu'elle est utilisée dans une déclaration utilisée?
Mise à jour: Cette question était Le sujet de mon blog en mars 2011 . Merci pour la grande question! P>
La réponse d'Andrew Hare est correcte; Je voulais juste ajouter une note supplémentaire intéressante. L'optimisation que nous émettons - de l'utilisation de Callvirt contraint pour sauter la boxe lorsque cela est possible - est en fait strictement parlant une violation de la spécification C #. La spécification indique que le choix enfin que nous générons pour une ressource de type de valeur est la suivante: P>
finally { ((IDisposable)resource).Dispose(); }
J'ai parfois bouleversé le manque de syntaxe de spécifier un "réinterpret sans boxe". Étant donné que ressource code> doit être d'un type qui satisferait une contrainte code> indisposable code>, je me demande si la spécification pourrait dire que le comportement serait équivalent à appeler
statique annulation statique < T> (Ref t it) où il: Idisposable {IT.Dispose ();} code>, sauf que le compilateur C # générerait probablement le code en ligne [même si le compilateur C # ne l'est pas en ligne , il semblerait que la gigue pourrait].
Bonjour Eric, je me demande si le Callvirt contraint est, à ce jour, toujours une violation de la spécification C #.