Différence entre la coulée en C # et VB.NET
Question
Le code suivant fonctionne très bien en C #.
Int32 a, b;
Int16 c;
a = 0x7FFFFFFF;
b = a & 0xFFFF;
c = (Int16)b;
Mais cet accident de code avec un OverflowException VB.NET .
Dim a, b As Int32
Dim c As Int16
a = &H7FFFFFFF
b = a And &HFFFF
c = CType(b, Int16)
Les deux extraits de code semblent la même chose pour moi. Quelle est la différence et comment puis-je obtenir le code C # converti en VB.NET?
La solution
De MSDN :
Pour l'arithmétique, la coulée, ou opération de conversion de lancer une OverflowException, l'opération doit avoir lieu dans un contexte contrôlé. Par défaut, les opérations arithmétiques et débordements dans Visual Basic sont vérifiés; en C #, ils ne sont pas. Si l'opération se produit dans un contexte sans contrôle, le résultat est tronqué en supprimant les bits de poids fort qui ne rentrent pas dans le type de destination.
EDIT: Si vous allez au code du port de C # à VB.NET, vous pouvez être intéressé par les différences de . Vous pouvez également comparer et définir explicitement pour être les mêmes que les paramètres par défaut dans C # (en cas de besoin).
Autres conseils
Première place: Je crois comprendre est que CType (b, Int16) ne sont pas les mêmes que (Int16) b. La première est une conversion de type (CType) et l'autre est un casting. (Int16) b correspond à DirectCast (b, Int16) plutôt que CType (b, Int16).
La différence entre les deux (comme indiqué sur le site MSDN) est que CType réussit tant qu'il y est une conversion valide, cependant, DirectCast nécessite le type de l'objet d'exécution être le même, et en tant que tel, vous tous « faisons est de dire le compilateur au moment de la conception que cet objet est de ce type plutôt que de dire à convertir ce type.
Voir: http://msdn.microsoft. com / fr-fr / bibliothèque / 7k6y2h6x (VS.71) .aspx
Le problème sous-jacent est bien que vous essayez de convertir un entier de 32 bits en un nombre entier de 16 bits qui est ... [Il me manque le mot que je besoin, peut-être quelqu'un peut l'insérer ici pour moi] lossy. La conversion de 16 bits à 32 bits est autorisé car il est sans perte, conversion de 32 bits à 16 bits est défini. Pourquoi cela fonctionne en C # vous pouvez voir @ réponse de Roman - ce qui a trait au fait que C # ne vérifie pas le trop-plein
. La valeur résultante des résultats &H7FFFFFFF And &HFFFF
à UInt16.MaxValue (65535) UInt16 va de 0 à 65535, vous essayez de caser cela dans Int16 qui va de -32768 à 32767 qui, comme vous pouvez le voir ne va pas travail. De plus, le fait que cette valeur pourrait entrer dans une UInt16 est pure coïncidence, l'ajout de deux entiers 32 bits et en essayant de les entasser dans un 16 entier bits (courte) serait souvent causer un débordement et je donc dire que c'est une opération intrinsèquement dangereuse.
http://www.cnblogs.com/liujq007/ archives / 2010/12/04 / 1896059.html
Résumé:
Pour un type non signé:. Est-ce juste et opérateur ou une méthode 2er
Dim a As Byte = CByte(300 And &HFF)
Pour type signé: déplacement vers la gauche de n bits, puis n bits de décalage à droite, ce qui est d'élargir le bit signé. n = (sizeof (type 1) - sizeof (type 2)) * 8 ou VB: utiliser Len (Nouveau type) au lieu de sizeof (type)
Dim a As Short = CShort(34042 << 16 >> 16)
Vous trouverez les détails du lien ci-dessous.
?CType(b, Int16)
Constant expression not representable in type 'Short'.
?b
65535
?directcast(b, Int16)
Value of type 'Integer' cannot be converted to 'Short'.
?int16.TryParse(b.ToString(), c)
False
Vous pouvez tronquer ce genre de débordement avec une structure.
<StructLayout(LayoutKind.Explicit)> _
Public Structure int3216
<FieldOffset(0)> Public i32 As Int32
<FieldOffset(0)> Public i16high As Int16
<FieldOffset(2)> Public i16low As Int16
End Structure
...
Dim _i3216 As int3216
_i3216.i32 = a And &HFFFF
c = _i3216.i16low
Je suis tombé sur cette question lors de la recherche d'une solution pour convertir un court et obtenir le résultat de trop-plein avec l'erreur de trop-plein. Je trouve ici une solution:
http://bytes.com/ sujet / visuel-base-net / réponses / 732622-problèmes transtypage-vb-net
à mi-chemin en bas de la page est la suivante:
Le vieux, VB « bonne » truc de « pas de côté » vers hexadécimaux et retour fonctionne toujours!
Dim unsigned as UInt16 = 40000
Dim signed as Int16 = CShort(Val("&H" & Hex(unsigned)))
il semble fonctionner assez lisse!