Ответ 1
Bool довольно особенный, он возвращается к решению Денниса Ричи, чтобы не дать C-языку тип bool. Это привело к тому, что многие разработчики хаоса, языка и операционной системы добавили его сами и сделали несовместимый выбор.
Он был добавлен в Winapi как BOOL typedef. Это маршалинг по умолчанию, если вы не навязываете другой тип. Typedef-ed как int, чтобы поддерживать его совместимость с C, занимает 4 байта, как вы узнали. И выровняется по 4, как вы узнали, как и любой int.
Он был добавлен в С++. Без спецификации размера большинство реализаций компилятора С++ выбрали один байт для хранения. В частности, компилятор Microsoft С++, наиболее вероятная реализация, с которой вы будете взаимодействовать.
Он был добавлен в COM Automation как VARIANT_BOOL. Первоначально он был нацелен на новую модель расширения для Visual Basic, чтобы избавиться от ограничений VBX, и она стала чрезвычайно популярной, и практически любая среда исполнения на Windows теперь поддерживает ее. В то время VB сильно пострадал от чувствительности 16-разрядной операционной системы, VARIANT_BOOL занимает 2 байта.
Все три среды среды выполнения, вероятно, являются мишенями для взаимодействия в программе на С#. Очевидно, что дизайнеры CLR имели очень трудный выбор, чтобы выбрать между 1, 2 и 4 байтами. Невозможно выиграть, в то время как CLR делает попытку догадки в COM-взаимодействии, он не может знать, пытаетесь ли вы взаимодействовать с api или C-программой на основе C. Поэтому они сделали единственный логический выбор: ни один из них.
Структура или тип класса, который содержит bool, никогда не будет смягчаться. Даже когда вы применяете [MarshalAs (UnmanagedType.U1)], тот, который сделает его совместимым с типом CLR. Не так уверен, что это было хорошее решение, но это было то, что они сделали, поэтому нам придется иметь дело с этим.
Получение blittable структуры очень желательно, это позволяет избежать копирования. Он позволяет встроенному коду напрямую обращаться к управляемой куче и стеку. Довольно опасный и много сломанной декларации пинкока испортил кучу GC без обычной выгоды от небезопасного уведомления по ключевым словам. Но невозможно биться за скорость.
Вы получаете blittable struct, не используя bool
. Вместо этого используйте byte
. Вы все равно можете вернуть bool, обернув элемент структуры с помощью свойства. Не используйте автоматически реализованное свойство, вы должны заботиться о позиции байта. Таким образом:
struct MyStruct
{
private byte _f;
public bool f {
get { return _f != 0; }
set { _f = value ? 1 : 0; }
}
}
Собственный код не обращает внимания на свойство. Не волнуйтесь о служебных затратах времени исполнения для getter и setter, оптимизатор джиттера заставляет их исчезнуть, и каждый из них превращается в одну команду процессора.