zoukankan      html  css  js  c++  java
  • 《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类型。

    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中每个字段的改变都会影响另一个字段的值。

  • 相关阅读:
    git的使用
    模块化的 require 和 import的区别
    Javascript模块化编程(二)commonJS规范和AMD规范
    Javascript模块化编程(三):require.js的用法
    SQL精华语句
    Convert sql 函数格式
    sql分页存储过程(汇总)
    jira和svn结合
    使用Java Service Wrapper 把Java程序作为Windows系统服务
    Eclipse使用技巧
  • 原文地址:https://www.cnblogs.com/wang_yb/p/2084945.html
Copyright © 2011-2022 走看看