《CLR Via C# 第3版》笔记之(五) - C#中的伪Union类型
一直以为像C#这种内存自动回收的语言,开发人员无法操作其在内存的布局。现在才知道,CLR也提供了相应的接口,让我们可以更细粒度的对代码进行控制。
主要内容
- C#中控制内存布局的Attribute
- 模拟C#中的Union类型
1. C#中控制内存布局的Attribute
为了控制自己定义的类或结构在内存中的布局,CLR提供了System.Runtime.InteropServices.StructLayoutAtrribute这个Attribute。
这个Attribute的构造器中提供了3种Layout:
1)LayoutKind.Auto : 由CLR自动排列字段
2)LayoutKind.Explicit :让CLR保持你自己的字段布局
3)LayoutKind.Sequential :利用偏移量在内存中显示排列字段
如果不指定StructLayoutAtrribute,CLR会选择它认为最好的布局。
默认情况下,Microsoft C#编译器对于引用类型选择LayoutKind.Auto,对值类型选择LayoutKind.Sequential。
当然,根据自己的需要可以手动修改。
2. 模拟C#中的Union类型
通过指定LayoutKind.Explicit,将结构体中每个字段开始位置的偏移量都指定为0来模拟Union类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | using System; using System.Runtime.InteropServices; class Test { static void Main() { Union u = new Union(); // 初始化后Union中的值均为0 Console.WriteLine( "after initialized: m_a=" +u.m_a + " m_b=" +u.m_b); // m_a赋予最大值后,m_b也随之改变 u.m_a = Byte.MaxValue; Console.WriteLine( "after [u.m_a = Byte.MaxValue]: m_a=" + u.m_a + " m_b=" + u.m_b); // m_b赋予的值大于m_a上限后,m_a溢出后重新计算为0 // 如果m_b=Byte.MaxValue + 2,依次类推,m_a溢出后重新计算为1 u.m_b = Byte.MaxValue + 1; Console.WriteLine( "after [u.m_b = Byte.MaxValue + 1]: m_a=" + u.m_a + " m_b=" + u.m_b); Console.ReadKey( true ); } } [StructLayout(LayoutKind.Explicit)] public struct Union { [FieldOffset(0)] public Byte m_a; [FieldOffset(0)] public Int32 m_b; } |
如上所示,结构体Union中每个字段的改变都会影响另一个字段的值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人