Что на самом деле делает LenB с параметрами без строки

У меня есть этот фрагмент кода, который конвертируется из vb6 в vb.net. Мне нужно знать, что делает LenB в этом фрагменте кода.

Dim singleValue As Single 'var for conversion use(4byte -> 1single)'
Dim bytes() As Byte
Dim valueB() As Byte 'this gets set elsewhere and is redim-d to its size'

For n = 0 To CDbl(ItemNumberCombo.Text) - 1
    'bytes() -> single'
    'UPGRADE_ISSUE: LenB function is not supported.'
    ReDim bytes(LenB(singleValue) - 1)
    bytes(3) = valueB(n * 4)
    bytes(2) = valueB(n * 4 + 1)
    bytes(1) = valueB(n * 4 + 2)
    bytes(0) = valueB(n * 4 + 3)
    'UPGRADE_ISSUE: LenB function is not supported.'
    'UPGRADE_ISSUE: VarPtr function is not supported. '
    Call memcpy(VarPtr(singleValue), VarPtr(bytes(0)), LenB(singleValue))
    'display the result'
    DText(n).Text = VB6.Format(singleValue, "0.000000E+00") 'CStr(singleValue)'
    If DataSaveCheckBox.CheckState = 1 And FileNameText.Text <> "" Then
        csvOutput = csvOutput & DText(n).Text & ","
    End If
Next n

Правильно ли я полагаю, что байты всегда уменьшаются до одинакового размера? Судя по всему, 4 элемента.

Зачем тогда использовать LenB для ReDim, если можно просто использовать номер? И почему ReDim вообще в шлейфе?

Ответов (2)

Решение

LenB () возвращает длину переменной в байтах. Самый распространенный пример - для строк, где он возвращает размер строки в байтах, а не количество символов, независимо от кодировки символов. Для других типов он возвращает размер объекта - размер одного существа 4. Причина, по которой они это сделали, состоит в том, что они хотели, чтобы код выжил, если будущая версия Visual Basic когда-либо изменит размер одного (не говоря уже о жесткое кодирование числа 4 при присвоении байтовому массиву).

При обновлении LenB () до .Net для строк используйте, System.Text.Encoding.Unicode.GetBytes() чтобы получить массив, уже заполненный байтами текста строки. Помните, что .Net всегда внутренне использует Unicode для строк. Если вам действительно нужна другая кодировка, в пространстве имен Encoding есть несколько альтернатив. Для других типов используйте BitConverter класс. В любом случае, не переходите построчно, так как новые методы избавляют от большого количества загруженной работы.

Вот - я помогу вам с преобразованием:

(ранее)

Dim csvOutput As New StringBuilder()

(потом)

Dim valueB() As Byte 'this gets set elsewhere and is redim-d to its size'
Dim singleValue As Single 'var for conversion

' Included because the original developer was concerned the size of a single could change
Dim singleSize As Integer = BitConverter.GetBytes(singleValue).Length 

Dim NumberItems As Double
If Double.TryParse(ItemNumberCombo.Text, NumberItems) Then
    For n As Integer = 0 To NumberItems - 1
        singleValue = BitConverter.ToSingle(valueB, n * singleSize)

        'display the result
        DText(n).Text = singleValue.ToString("E6") 'CStr(singleValue)
        If DataSaveCheckBox.CheckState = 1 AndAlso Not String.IsNullOrEmpty(FileNameText.Text) Then
            csvOutput.Append(DText(n).Text & ",")
        End If
    Next n
Else
    ' Handle Invalid ComboBox value here- may not be an issue for you
End If

Обратите внимание , что этот код также демонстрирует , StringBuilder как много лучшего способа для создания данных в формате CSV, с AndAlso оператором, .TryParse() методами, String.IsNullOrEmpty() и стандартный формат строка, все из которых предназначена для замены конструкций или методов из VB6.

Пытаться объяснить плохой код ... тщетно. Интересный способ заполнить сингл загрузкой байтового массива.

Функция LenB дает вам длину переменной в байтах. Да, он всегда будет возвращать 4 при передаче типа переменной Single.

Я предполагаю, что redim таков, что массив инициализируется, а не сохраняется. Но поскольку затем он назначает все 4 байта, это технически не требуется и, вероятно, является просто защитным программированием. Защитное программирование также может объяснить LenB. В случае, если Single изменит размер в будущем.