J'ai un projet XNA 3.0 qui compilait juste bien dans VS2008, mais cela donne des erreurs de compilation dans VS2010 (avec XNA 4.0 CTP). L'erreur:
Impossible d'utiliser "STAPTPR" local fixe dans une méthode anonyme, une expression Lambda ou une expression de requête p> blockquote>
STAPTPTR code> est un
flotteur fixe * code> dans un tableau, utilisé à l'intérieur d'un
parallel.for code> Expression Lambda de < Code> System.threading code>. Comme je l'ai dit, cela compilait et couru juste bien sur VS2008, mais ce n'est pas sur VS2010, même lorsque vous ciblez .NET 3.5. P>
a-t-il changé dans .NET 4.0, et même si, ne devrait-il pas toujours compiler lorsque je choisis .NET 3.5 comme cadre cible? La recherche du terme "ne peut pas utiliser" local fixe "des rendements exactement un résultat (inutile), à la fois dans Google et Bing. P>
Si cela a changé, quelle est la raison pour cela? Je peux imaginer capturer un code> fixe code> de type pointeur dans une fermeture pourrait être un peu bizarre, c'est pourquoi? Donc, je suppose que c'est une mauvaise pratique? Et avant que quiconque ne demande: non, l'utilisation de pointeurs n'est pas absolument critique ici. Je voudrais toujours savoir cependant :) p>
EDIT: STRUT> Comme demandé, un échantillon de code (non de mon programme, évidemment) qui reproduit l'erreur suivante: p>
xxx pré> La compile ci-dessus dans VS2008 (Eh bien, à part la référence à
Parallèle code>, mais toute autre expression de Lambda fera), mais ne va pas dans VS2010. P> P>
5 Réponses :
Une explication pourrait être que la valeur d'une variable est prise à l'exécution de la fermeture et non la définition. Dans votre exemple, cela ne ferait probablement aucun mal, mais dans d'autres cas, cela pourrait être. Donc, pour enseigner la bonne pratique, il est complètement interdit d'empêcher toutes sortes de bugs intéressants. P>
Pinceaux fixes un pointeur pendant la durée du bloc. Si vous deviez stocker le délégué pour invoquer ultérieurement après l'évolution du bloc, le collecteur des ordures pourrait déplacer l'objet entre la lecture de la Lambda et lorsque la Lambda est invoquée. Pourquoi cibler un cadre différent n'aide pas, c'est parce que cela est en cours d'exécution par la langue / le compilateur, pas le temps d'exécution (s'il s'agissait de l'exécution, il serait signalé via une exception ou similaire au moment de l'exécution, pas par le compilateur au moment de la compilation). P>
Ah, donc il définit simplement la version d'exécution et n'utilise pas un plus ancien compilateur? Logique. À propos de l'épinglage, oui, c'est un risque, mais je pourrais tout aussi bien déclarer un champ d'instance sur le type qui vit également plus longtemps que le bloc fixe, ce qui lui permet d'indiquer un emplacement invalide. Pourtant, c'est toujours possible.
Je ne pense pas qu'il serait possible de vérifier statiquement tous les scénarios qu'un pointeur épinglé pourrait devenir invalide, finalement, une personne peut toujours utiliser Gchandle. Ce chèque représente probablement simplement un "meilleur effort" pour éviter les problèmes non évidents qui peuvent s'ensuivre du code comme celui-ci.
the DOCO Dites Vous n'êtes pas autorisé à accéder à un code dangereux dans une méthode anonyme et les mêmes restrictions s'appliquent à Lambdas, alors je pense que cela peut être votre problème. Avez-vous l'erreur de compilateur non? P>
Cela fonctionne. Fondamentalement, nous avons éliminé la Lambda contenant un pointeur dangereux et l'a remplacé par un délégué à une instance d'une classe déclarée à l'intérieur du bloc code> (code> code> pre> xxx pre>
me ressemble. NET 4 Ajout d'une tentative de demi-arsed au moment d'intercalaire un accès à la mémoire fixe dans le compilateur. Dans le bloc de code ci-dessus, vous pouvez définir non rafare code> en dehors du bloc code> fixe Accéder au tableau après le bloc code> fixe code>. Donc, ce n'est pas parfait ... p> p>
Le compilateur est correct de rejeter ce code. Fixe ne peut être utilisé que sur les variables locales et les variables capturées par une fermeture ne sont pas des variables locales, elles sont hissées dans la classe utilisée pour maintenir l'état pour la fermeture. P>
Pouvez-vous s'il vous plaît poster le code qui provoque l'erreur.
Eh bien, il n'y a pas grand chose à poster, c'est exactement ce que l'erreur a dit: l'utilisation d'un pointeur dans une expression lamdba.
Néanmoins, poster un code court mais complet que nous pouvons expérimenter serait une bonne chose (TM).