C#正真实现C++中的数值型位域(非位标志)

C++中的位域成员有2种用途。一种是存放位标志的,比如下面这种。

struct flags
{
	unsigned int flag1:1;
	unsigned int flag2:1;
}

C#中可以很方便地用 [Flags] Enum 实现,网上找C#实现位域的都是这种。

 

还有一种是存放数值的,比如今天碰到一个问答,是下面这样的结构。

struct MWORD
{
	unsigned int m_nBase:30;
	unsigned int m_nMul:2;
}

原先C++中Mul成员的取值范围是0..3。
假如还用 [Flags] Enum 实现,按位与操作后取值是零散的{0,0x40000000,0x80000000,0xC0000000},用起来不方便。
需要把原先C++自动实现的各种位操作封装到属性中:

//C#的控制台工程
using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    [StructLayout(LayoutKind.Sequential)]
    public struct MWORD
    {
        public uint value; //暴露出来方便调试,最终版应该是private的。
        public uint Base
        {
            get
            {
                return this.value & 0x3FFFFFFF;
            }
            set
            {
                this.value = (this.value & 0xc0000000) | (value & 0x3FFFFFFF);
            }
        }
        public uint Mul
        {
            get
            {
                return (this.value >> 30) & 0x00000003;
            }
            set
            {
                this.value = (this.value & 0x3FFFFFFF) | ((value & 0x00000003)<<30);
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MWORD v = new MWORD();
            Console.WriteLine("SizeOf()={0}",Marshal.SizeOf(v));
            v.value = 0xffffffff;
            Console.WriteLine("value=0x{0:X8}, Base={1}, Mul={2}", v.value, v.Base, v.Mul);
            v.Base = 0x23456789;
            Console.WriteLine("value=0x{0:X8}, Base={1}, Mul={2}", v.value, v.Base, v.Mul);
            v.Mul = 2;
            Console.WriteLine("value=0x{0:X8}, Base={1}, Mul={2}", v.value, v.Base, v.Mul);
            Console.ReadLine();
        }
    }
}

输出:

SizeOf()=4
value=0xFFFFFFFF, Base=1073741823, Mul=3
value=0xE3456789, Base=591751049, Mul=3
value=0xA3456789, Base=591751049, Mul=2

你可能感兴趣的:(C#,位域,c#,c++)