You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用StructLayout(LayoutKind.Sequential)的双布尔结构体占8字节?

.NET结构体中bool序列化的字节布局问题

问题分析

你的结构体序列化后得到01 00 00 00 01 00 00 00的原因,既不是单纯的内存填充,而是**.NET默认情况下将bool类型作为4字节(32位)整数处理,同时遵循小端序存储**,具体细节如下:

核心原因:.NET中bool的默认布局规则

  • 在CLR的默认结构体布局(LayoutKind.Sequential且未指定Pack值)中,bool类型的默认大小为4字节,而非1字节。这是CLR为了内存对齐效率做出的默认设定,和C++等语言的默认bool大小不同。
  • 当bool值为true时,其对应的整数值为1,小端序存储下就会呈现为01 00 00 00;两个bool成员就会依次占用4字节空间,最终得到8字节的十六进制结果。

为什么ChatGPT的结论不符

ChatGPT的说法混淆了不同语言的默认规则:在C++等语言中bool默认占1字节,但.NET的默认行为是将结构体中的bool按4字节对齐并存储,除非你显式修改序列化规则。

如何修改得到紧凑的1字节bool布局

如果希望两个bool紧挨着占用2字节,可以通过两种方式实现:

  1. 给每个bool成员添加[MarshalAs(UnmanagedType.U1)]属性,强制将其序列化为1字节的无符号整数:
    [StructLayout(LayoutKind.Sequential)]
    public struct SystemServiceStatus {
        [MarshalAs(UnmanagedType.U1)]
        public bool isSystemUiOverlaid;
        [MarshalAs(UnmanagedType.U1)]
        public bool isInBackgroundExecution;
    }
    
  2. 给结构体添加Pack = 1的布局属性,强制所有成员按1字节对齐(会影响整个结构体的内存布局):
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct SystemServiceStatus {
        public bool isSystemUiOverlaid;
        public bool isInBackgroundExecution;
    }
    

修改后,两个true值序列化后的十六进制就会是01 01。

内容的提问来源于stack exchange,提问作者Steinbitglis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:42:09