《CL福睿斯 Via C# 第2版》笔记之(五) – C#中的伪Union类型

一贯以为像C#那种内部存款和储蓄器自动回收的言语,开发职员不能操作其在内部存款和储蓄器的布局。未来才领会,CL冠道也提供了相应的接口,让大家得以更细粒度的对代码进行支配。

C#,重在内容

  • C#中央控制制内部存款和储蓄器布局的Attribute
  • 模拟C#中的Union类型

1. C#中央控制制内部存款和储蓄器布局的Attribute

为了控制自个儿定义的类或协会在内存中的布局,CL景逸SUV提供了System.Runtime.InteropServices.StructLayoutAtrribute这几个Attribute。

以此Attribute的构造器中提供了3种Layout:

1)LayoutKind.Auto : 由CL酷威自动排列字段

2)LayoutKind.Explicit :让CL酷威保持您自个儿的字段布局

3)LayoutKind.Sequential :利用偏移量在内部存款和储蓄器中显得排列字段

设若不钦点StructLayoutAtrribute,CL凯雷德会选择它认为最棒的布局。

默许情形下,Microsoft
C#编写翻译器对于引用类型采纳LayoutKind.Auto,对值类型选拔LayoutKind.Sequential。

当然,根据自个儿的须求能够手动修改。

2. 模拟C#中的Union类型

因而内定LayoutKind.Explicit,将结构体中各种字段起先位置的偏移量都内定为0来模拟Union类型。

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中各样字段的改变都会潜移默化另1个字段的值。

相关文章