Pour le code suivant, je reçois une erreur de temps de compilation, *
'int' n'est pas un type de référence comme requis par l'instruction de verrouillage p> blockQuote>
xxx pré> mais aucune erreur pour cela: p>
xxx pré> Je comprends qu'un type de valeur ne doit pas être utilisé pour le verrouillage dû aux complications découlant de la boxe. Mais, alors pourquoi fonctionne-t-il avec le moniteur? P> P>
5 Réponses :
La raison pour laquelle est-ce que la serrure est une construction de langue et un compilateur choisit d'imposer une sémantique supplémentaire sur l'expression. Monitor.enter est simplement un appel de méthode et le compilateur C # ne case pas particulièrement l'appel de quelque manière que ce soit et que cela passe donc une résolution normale sur la surcharge et la boxe. P>
Je dirais que c'est parce que moniteur.enter () code> est un appel de méthode, de sorte que le compilateur effectue la boxe automatiquement, tandis que verrouillage () code> est un élément syntaxique, Donc, le compilateur peut vérifier et lancer une erreur sur les types de valeur. P>
Je ne pense pas qu'il y ait une vérification. N'est pas verrouillage juste développé avec un monito.enter dans un bloc d'essai et moniteur.exit dans le bloc enfin.
Non, il est étendu à cela, mais d'abord le compilateur Spots si vous êtes stupide sur le chemin ...
Vous ne devez absolument pas utiliser La manière recommandée de faire le verrouillage consiste à créer un objet loadonly code> code> et verrouille dessus. Pour une méthode statique, vous pouvez utiliser un objet statique code> code>. P> moniteur.enter code> sur un int code>. La raison pour laquelle cela fonctionne est que le int code> est en boîte, alors que si vous stockez une référence à la valeur en boîte, vous verrez un objet temporaire, ce qui signifie que vous ne pouvez pas appeler moniteur.exit code> sans obtenir une exception. p>
juste hors de curiosité, que faites-vous avec la variable 'I' qui l'oblige à être verrouillée? Il peut être plus efficace d'utiliser la classe verrouillée si tout votre part est un incrément ou quelque chose: La classe verrouillée est l'outil de synchronisation de fil de poids la plus léger qui fournit et pour des incréments simples , décréments, lit ou échanges, c'est la meilleure option. p> Si vous essayez de synchroniser un bloc de comportement, je créerais simplement un objet pouvant être utilisé comme racine de synchronisation: p>
Purement hors d'intérêt ... je suis conscient de la classe verrouillée. Merci.
La spécification du compilateur définit Le comportement de verrouillage comme si : p>
Le type d'heure de compilation de l'expression d'un relevé de verrouillage doit être un paramètre de type de référence ou un paramètre de type (§25.1.1) connu pour être un type de référence. C'est une erreur de compilation pour la Compilez le type d'heure de l'expression pour désigner un type de valeur. p> blockQuote>
Il définit ensuite ce qu'il est équivalent à tant que cela compile fort> p>
Etant donné que moniteur.exit est juste un appel de méthode sans aucune contrainte, il n'empêchera pas le compilateur de la boxe automatiquement de l'INT et de passer sa méthode joyeuse (et très) incorrecte. P>
verrouillage code> n'est pas simplement syntaxique sucre de la même manièreforeach code> n'est pas simplement le sucre syntaxique. La transformation IL résultante est pas em> présentée au reste du code comme si c'était ce qui avait été écrit. P>in
foreach code> Il est illégal de modifier la variable d'itération (malgré le niveau d'IL au niveau de l'IL dans le code de sortie résultant qui l'empêcherait). En verrouillage, le compilateur empêche la compilation des types de valeur connus de la compilation, en dépit d'une fois que l'IL résultant ne se souciait pas de cela. P>comme un de côté:
En théorie, le compilateur pourrait être «béni» avec une connaissance intime de cette méthode (et d'autres) de sorte que cela aperçu des cas évidents de cet événement, mais il est fondamentalement impossible em> pour toujours repérer cela au moment de la compilation (considérer un objet passé d'une autre méthode, assemblage ou par réflexion), si vous souciez de repérer de tels cas, serait probablement contre-productif. P>Plus le compilateur connaît les internes de l'API, plus vous aurez des problèmes si vous souhaitez modifier l'API à l'avenir. P>
Il est possible que l'on puisse ajouter une surcharge de moniteur. Cela se conformerait aux spécifications du moniteur (même si elle serait probablement hideuse) mais causerait des problèmes énormes pour que le compilateur plus âgé empêche encore une opération devenue légale. P>