2010-08-19 5 views
11

Je trouve ce comportement de TryCast dans .NET 4.0/VS 2010 plutôt confus. À mon avis, TryCast fonctionne comme DirectCast, mais retournera Nothing au lieu de lancer une exception si un cast n'est pas possible.TryCast échoue où DirectCast fonctionne (.NET 4.0)

VS 2010/.NET 4

?TryCast(CType(1, Object), String) 
Nothing 
?DirectCast(CType(1, Object), String) 
"1" 

VS 2008/.NET 3.5

?TryCast(CType(1, Object), String) 
Nothing 
?DirectCast(CType(1, Object), String) 
Cannot convert to 'String'. 

Le .NET 3.5 résultats sont cohérents avec ce que je crois TryCast fait ... .NET 4 n'est cependant pas.

Quelqu'un peut-il me diriger dans la meilleure direction pour lancer un objet en toute sécurité dans .NET 4?

Répondre

16

Basé sur vos échantillons de code commençant par le ? Je suppose que vous utilisez la fenêtre immédiate pour effectuer votre test correct? Le problème avec cette approche est que la fenêtre immédiate est une interprétation plutôt qu'une évaluation réelle. Cela le rend vulnérable aux bogues de cas de coin subtiles et c'est en effet l'un d'entre eux.

Si vous prenez votre exemple de code et l'ajoutez à une simple application console VB.Net, vous trouverez que le comportement de 2010 est identique au comportement de 2008 (déclenche une exception).

EDIT

Alors pourquoi cette régression est arrivé? En 2010, j'ai complètement réécrit le moteur de débogage VB EE (évaluateur d'expression). L'ancienne base de code dont j'ai hérité était simplement trop coûteuse pour être maintenue. Au point que l'ajout de nouvelles fonctionnalités au moteur était plus coûteux que de le réécrire à partir de zéro avec une meilleure architecture qui incluait les nouvelles fonctionnalités. Comme indiqué précédemment, les évaluations de débogage sont une interprétation plus qu'une exécution de code. Il force la duplication de certains algorithmes entre l'EE et le CLR/compilateur. L'un des domaines où la duplication se produit est dans la logique de coulée. Il n'y a aucun moyen de demander au débogueur CLR de lancer un objet de temps de débogage, il est de la responsabilité de l'EE de déterminer si la distribution spécifiée en langue est effectivement valide.

L'ancienne logique de lancement EE comportait de nombreux bogues (en particulier dans le domaine des génériques et des tableaux). La nouvelle infrastructure est très proche des lignes directrices du CLR. Cependant, vous n'aurez jamais la parité à 100%, car cela interdirait les expressions très utiles dans l'EE (j'écrirai peut-être un article de blog à ce sujet dans le futur). Mais pour la plupart des cas, le comportement est valide.

Dans cet exemple particulier, j'ai ajouté un bogue subtil qui permet d'utiliser DirectCast d'une valeur tapée Object pour utiliser les opérateurs de conversion d'exécution de VB par rapport au comportement spécifié qui autorise uniquement les conversions CLR. Par conséquent, cette conversion réussit là où elle devrait échouer.

+0

Je viens de confirmer ce que vous avez suggéré. DirectCast() lance en effet une exception lorsqu'il est exécuté dans une évaluation réelle. Merci pour la clarification! – motto

+0

Ce serait vraiment bien si vous pouviez expliquer exactement ce qui s'est passé. – SLaks

+0

@ SLaks, ajouté une explication rapide. – JaredPar