В первом сценарии (ниже) окончательное целочисленное значение равно 255 (используется BitArray.SetAll(Boolean)
)
Во втором сценарии окончательное целочисленное значение равно 3 (что правильно. Установите биты для каждого индекса).
Я ожидаю, что оба должны вести себя одинаково. Но нет. Какая-то конкретная причина?
Сценарий 1:
BitArray myBA = new BitArray(2);
myBA.SetAll(true);
byte[] byteArray = new byte[8];
myBA.CopyTo(byteArray, 0);
Int64 finalInt = BitConverter.ToInt64(byteArray,0); //finalInt = 255
Сценарий 2:
BitArray myBA = new BitArray(2);
myBA[0] = true;
myBA[1] = true;
byte[] byteArray = new byte[8];
myBA.CopyTo(byteArray, 0);
Int64 finalInt = BitConverter.ToInt64(byteArray,0); //finalInt = 3 (which is expected.)
Попробуйте этот код на .netfiddle:
BitArray myBA = new BitArray(2);
myBA.SetAll(true);
byte[] byteArray = new byte[8];
//myBA.Length++;
myBA.CopyTo(byteArray, 0);
Int64 finalInt = BitConverter.ToInt64(byteArray,0);
Console.WriteLine(finalInt);
Он печатает неправильные 255, однако, если вы просто увеличиваете Length
перед копированием в массив (раскомментируйте закомментированную строку), он печатает правильные 3!
Это говорит мне, что это какая-то ошибка в .NET framework. Кроме того, если вы переключите платформу на .NET 5 или .NET Core, вы всегда получите правильную «3», даже если не увеличите Length
.
Глядя на исходный код .NET framework и .NET Core, я думаю, что происходит следующее:
В среде .NET SetAll(true)
устанавливает все int
в базовом int[]
на -1
(все единицы), независимо от Length
битового массива. Только когда вы увеличиваете Length
, он «добавляет» новый 0. CopyTo
, похоже, не учитывает тот факт, что, когда Length
битового массива не кратно 8, он не должен копировать весь последний байт. Таким образом, он копирует весь последний байт, который состоит из единиц, создавая 255, которые вы видите.
OTOH, CopyTo
в .NET Core учитывает это:
// last byte is not aligned, we will directly copy one less byte
А также в строке 925:
// mask the final byte
который предлагает скопировать только часть последнего байта. Кроме того, SetAll(true)
в .NET Core только устанавливает биты myBA.Length
в 1 в базовом int[]
и очищает остальные биты, которые не выровнены с байтом.
Вот проблема (Спасибо Мэтью Уотсону, который нашел ее!) в репозитории .NET Core, которая, кажется, сейчас обрабатывается. Вероятно, это объясняет, почему ошибка отсутствует в .NET Core.
Это может быть проблема на GitHub, которая была исправлена: github.com/dotnet/runtime/issues/17765