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?

Était-ce utile?

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.

Avez-vous essayé d'utiliser DirectCast(b, Int16)? CType n'est pas identique à un casting C #.

est un article comparant les performances de DirectCast et CType, ainsi que d'aller plus en détail quand une ou l'autre doit être utilisé.

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!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top