2012-02-09 13 views
6

Dlaczego odlewanie boolean do byte w .NET daje następujące wyniki?Konwersja wartości Boolean na Byte w VB.NET

kod Snippit:

Dim x As Boolean = 1 
Dim y As Byte = x 'Implicit conversion here from Boolean to Byte 

System.Diagnostics.Debug.Print(_ 
    "x = " & x.ToString _ 
    & " y = " & y.ToString _ 
    & " (bool)(1) = " & CType(1, Boolean).ToString _ 
    & " (byte)((bool)1) = " & CType((CType(1, Boolean)), Byte).ToString) 

wyjściowa:

x = True
Y = 255
(bool) (1) = True
(bajtów) ((Bool) 1) = 255

Dlaczego True (w hich zwykle jest określany jako liczba całkowita reprezentująca 1) konwersji do 255 po odlaniu do byte?

+0

Ciekawe, że VB.NET umożliwia nawet rzutowanie logiki Boolean na bajt. W języku C# to nielegalna obsada. – vcsjones

+0

Jeśli zrobisz 'DirectCast()' w VB.NET automatycznie powie Ci, że jest to nielegalna obsada, ale jeśli użyjesz 'CType()' (co pokazałem), zrobi to jak wyżej. Chciałbym wiedzieć, jak "True", który jest powszechnie znany jako "1", przekłada się na "255" pod maską. Mnóstwo tutaj dziwnych castingów. – afuzzyllama

+0

Myślę, że to tylko zachowanie kompilatora. Emituje IL 'ldc.i4 FF 00 00 00', ale nie widzę niczego w specyfikacji, która mówi dlaczego. W bardzo prostych przypadkach kompilator właśnie optymalizuje odlew. – vcsjones

Odpowiedz

11

VB.NET kompilator obsługuje go jako zwężenie conve rsion. Z 10,0 VB.NET Spec:

zwężenie konwersje są konwersje, że nie można udowodnić na zawsze uda, konwersje, które są znane ewentualnie stracić informacji, a konwersje różnych domenach różnych typów wystarczający do zasług zwężenie notacji. Następujące konwersje są klasyfikowane jako konwersje zwężające:

  • Od Boolean do Byte, SByte, ushort, Krótka, UInteger, Integer ULong, Długi, dziesiętny, pojedynczy lub podwójny.

Od the docs:

Kiedy Visual Basic przekształca wartości numeryczne typu danych Boolean, 0 staje się fałszem, a wszystkie inne wartości stają True. Kiedy Visual Basic konwertuje wartości typu Boolean na typy liczbowe, Fałsz staje się 0, a Prawda -1.

Bajty nie są podpisane, więc otrzymasz 255 zamiast Two's Compliment.

4

wartość logiczną True w .NET jest przechowywana jako -1, co z kolei jest spowodowane 11111111 Two's Complement

Więc Dim x As Boolean = 1 konwertuje 1 do Boolean true

i Dim y As Byte = x konwertuje prawda do 11111111, która odpowiada 255

(Jeżeli zamiast tego napisał Dim z As Integer = x, z by = -1)

3

Wszystkie historyczne wersje Basica, które widziałem, które obsługują bitowe operatory Boole'a z liczbami całkowitymi, używały "zestawu bitów", tj. -1, jako wartości dla prawdziwych porównań. Tak więc, jeśli chcemy mieć wartość, która wynosi 9, jeśli a == b, lub zero, jeśli nie, można użyć wyrażenia 9 AND (a=b). Podczas gdy operator ?: obecny w C pozwala na takie kodowanie wyraźniej, użycie -1 dla "prawda" ma więcej praktycznych zalet niż wad w języku bez dyskretnego typu Boolean.

Podczas gdy vb.net jest własnym językiem, zupełnie oddzielonym od vb6, jest dużo kodu, który został przeniesiony z wersji vb6 na vb.net i może polegać na tym, że operatory porównania dają zestaw wszystkich bitów, gdy są prawdziwe.

0

Jeśli chcesz przekonwertować true do 1 i false do 0, użyj:

Convert.ToByte(Boolean) 

Link do dokumentacji Convert.ToByte(boolean).

W przeciwnym razie uzyskaj prawdziwą wartość -1, 0xFF.

Powiązane problemy