<p>I have a structure which I need to populate and write to disk (several actually).</p>

<p>An example is:</p>

<pre><code>byte-6    
bit0 - original_or_copy  
bit1 - copyright  
bit2 - data_alignment_indicator  
bit3 - PES_priority  
bit4-bit5 - PES_scrambling control.  
bit6-bit7 - reserved  
</code></pre>

<p>In C I might do something like the following:</p>

<pre><code>struct PESHeader  {
    unsigned reserved:2;
    unsigned scrambling_control:2;
    unsigned priority:1;
    unsigned data_alignment_indicator:1;
    unsigned copyright:1;
    unsigned original_or_copy:1;
};
</code></pre>

<p>Is there any way to do this in C# that would enable me to access the bits using the struct dereferencing dot operator? </p>

<p>For a couple of structures, I can just do bit shifting wrapped in an accessor function.</p>

<p>I have loads of structures to handle in this way, so I'm looking for something that's easier to read and quicker to write.</p>

[{'answer_id': 14466, 'author': 'Michael Stum', 'author_id': 91, 'author_profile': 'https://Stackoverflow.com/users/91', 'pm_score': 2, 'selected': False, 'text': '<p>Could an Enum with the Flags Attribute help maybe? See here:</p>\n\n<p><a href="https://stackoverflow.com/questions/8447/enum-flags-attribute#8460">What does the [Flags] Enum Attribute mean in C#?</a></p>\n'}, {'answer_id': 14475, 'author': 'Mark Cidade', 'author_id': 1659, 'author_profile': 'https://Stackoverflow.com/users/1659', 'pm_score': 5, 'selected': False, 'text': '<p>You want <a href="http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute(VS.71).aspx" rel="noreferrer">StructLayoutAttribute</a></p>\n\n<pre><code>[StructLayout(LayoutKind.Explicit, Size=1, CharSet=CharSet.Ansi)]\npublic struct Foo \n{ [FieldOffset(0)]public byte original_or_copy; \n  [FieldOffset(0)]public byte copyright;\n  [FieldOffset(0)]public byte data_alignment_indicator; \n  [FieldOffset(0)]public byte PES_priority; \n  [FieldOffset(0)]public byte PES_scrambling_control; \n  [FieldOffset(0)]public byte reserved; \n}\n</code></pre>\n\n<p>This is really a union but you can use it as a bitfield--you just have to be conscious of where in the byte the bits for each field are supposed to be. Utility functions and/or constants to AND against can help.</p>\n\n<pre><code>const byte _original_or_copy = 1;\nconst byte _copyright        = 2;\n\n//bool ooo = foo.original_or_copy();\nstatic bool original_or_copy(this Foo foo) \n{ return  (foo.original_or_copy &amp; _original_or_copy)  == original_or_copy;\n}    \n</code></pre>\n\n<p>There is also LayoutKind.Sequential which will allow you to do it the C way.</p>\n'}, {'answer_id': 14517, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 5, 'selected': False, 'text': '<p>By using an enum you can do this, but will look awkward.</p>\n\n<pre><code>[Flags]\npublic enum PESHeaderFlags\n{\n    IsCopy = 1, // implied that if not present, then it is an original\n    IsCopyrighted = 2,\n    IsDataAligned = 4,\n    Priority = 8,\n    ScramblingControlType1 = 0,\n    ScramblingControlType2 = 16,\n    ScramblingControlType3 = 32,\n    ScramblingControlType4 = 16+32,\n    ScramblingControlFlags = ScramblingControlType1 | ScramblingControlType2 | ... ype4\n    etc.\n}\n</code></pre>\n'}, {'answer_id': 14540, 'author': 'Mark Cidade', 'author_id': 1659, 'author_profile': 'https://Stackoverflow.com/users/1659', 'pm_score': 2, 'selected': False, 'text': '<p>A flags enum can work too, I think, if you make it a byte enum:</p>\n\n<pre><code>[Flags] enum PesHeaders : byte { /* ... */ }\n</code></pre>\n'}, {'answer_id': 14591, 'author': 'Adam Wright', 'author_id': 1200, 'author_profile': 'https://Stackoverflow.com/users/1200', 'pm_score': 7, 'selected': True, 'text': '<p>I\'d probably knock together something using attributes, then a conversion class to convert suitably attributed structures to the bitfield primitives. Something like...</p>\n\n<pre><code>using System;\n\nnamespace BitfieldTest\n{\n    [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]\n    sealed class BitfieldLengthAttribute : Attribute\n    {\n        uint length;\n\n        public BitfieldLengthAttribute(uint length)\n        {\n            this.length = length;\n        }\n\n        public uint Length { get { return length; } }\n    }\n\n    static class PrimitiveConversion\n    {\n        public static long ToLong&lt;T&gt;(T t) where T : struct\n        {\n            long r = 0;\n            int offset = 0;\n\n            // For every field suitably attributed with a BitfieldLength\n            foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())\n            {\n                object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);\n                if (attrs.Length == 1)\n                {\n                    uint fieldLength  = ((BitfieldLengthAttribute)attrs[0]).Length;\n\n                    // Calculate a bitmask of the desired length\n                    long mask = 0;\n                    for (int i = 0; i &lt; fieldLength; i++)\n                        mask |= 1 &lt;&lt; i;\n\n                    r |= ((UInt32)f.GetValue(t) &amp; mask) &lt;&lt; offset;\n\n                    offset += (int)fieldLength;\n                }\n            }\n\n            return r;\n        }\n    }\n\n    struct PESHeader\n    {\n        [BitfieldLength(2)]\n        public uint reserved;\n        [BitfieldLength(2)]\n        public uint scrambling_control;\n        [BitfieldLength(1)]\n        public uint priority;\n        [BitfieldLength(1)]\n        public uint data_alignment_indicator;\n        [BitfieldLength(1)]\n        public uint copyright;\n        [BitfieldLength(1)]\n        public uint original_or_copy;\n    };\n\n    public class MainClass\n    {\n        public static void Main(string[] args)\n        {\n            PESHeader p = new PESHeader();\n\n            p.reserved = 3;\n            p.scrambling_control = 2;\n            p.data_alignment_indicator = 1;\n\n            long l = PrimitiveConversion.ToLong(p);\n\n\n            for (int i = 63; i &gt;= 0; i--)\n            {\n                Console.Write( ((l &amp; (1l &lt;&lt; i)) &gt; 0) ? "1" : "0");\n            }\n\n            Console.WriteLine();\n\n            return;\n        }\n    }\n}\n</code></pre>\n\n<p>Which produces the expected ...000101011. Of course, it needs more error checking and a slightly saner typing, but the concept is (I think) sound, reusable, and lets you knock out easily maintained structures by the dozen.</p>\n\n<p>adamw</p>\n'}, {'answer_id': 5420979, 'author': 'Conrad', 'author_id': 610090, 'author_profile': 'https://Stackoverflow.com/users/610090', 'pm_score': 3, 'selected': False, 'text': "<p>While it is a class, using <code>BitArray</code> seems like the way to least reinvent the wheel. Unless you're really pressed for performance, this is the simplest option.  (Indexes can be referenced with the <code>[]</code> operator.)</p>\n"}, {'answer_id': 7636680, 'author': 'Christophe Lambrechts', 'author_id': 976896, 'author_profile': 'https://Stackoverflow.com/users/976896', 'pm_score': 3, 'selected': False, 'text': '<p>You could also use the <code>BitVector32</code> and especially the <a href="http://msdn.microsoft.com/en-us/library/system.collections.specialized.bitvector32.section.aspx" rel="noreferrer"><code>Section struct</code></a>. The example is very good.</p>\n'}, {'answer_id': 11145067, 'author': 'Zbyl', 'author_id': 407758, 'author_profile': 'https://Stackoverflow.com/users/407758', 'pm_score': 4, 'selected': False, 'text': "<p>As Christophe Lambrechts suggested BitVector32 provides a solution. Jitted performance should be adequate, but don't know for sure.\nHere's the code illustrating this solution:</p>\n\n<pre><code>public struct rcSpan\n{\n    //C# Spec 10.4.5.1: The static field variable initializers of a class correspond to a sequence of assignments that are executed in the textual order in which they appear in the class declaration.\n    internal static readonly BitVector32.Section sminSection = BitVector32.CreateSection(0x1FFF);\n    internal static readonly BitVector32.Section smaxSection = BitVector32.CreateSection(0x1FFF, sminSection);\n    internal static readonly BitVector32.Section areaSection = BitVector32.CreateSection(0x3F, smaxSection);\n\n    internal BitVector32 data;\n\n    //public uint smin : 13; \n    public uint smin\n    {\n        get { return (uint)data[sminSection]; }\n        set { data[sminSection] = (int)value; }\n    }\n\n    //public uint smax : 13; \n    public uint smax\n    {\n        get { return (uint)data[smaxSection]; }\n        set { data[smaxSection] = (int)value; }\n    }\n\n    //public uint area : 6; \n    public uint area\n    {\n        get { return (uint)data[areaSection]; }\n        set { data[areaSection] = (int)value; }\n    }\n}\n</code></pre>\n\n<p>You can do a lot this way. You can do even better without using BitVector32, by providing handmade accessors for every field:</p>\n\n<pre><code>public struct rcSpan2\n{\n    internal uint data;\n\n    //public uint smin : 13; \n    public uint smin\n    {\n        get { return data &amp; 0x1FFF; }\n        set { data = (data &amp; ~0x1FFFu ) | (value &amp; 0x1FFF); }\n    }\n\n    //public uint smax : 13; \n    public uint smax\n    {\n        get { return (data &gt;&gt; 13) &amp; 0x1FFF; }\n        set { data = (data &amp; ~(0x1FFFu &lt;&lt; 13)) | (value &amp; 0x1FFF) &lt;&lt; 13; }\n    }\n\n    //public uint area : 6; \n    public uint area\n    {\n        get { return (data &gt;&gt; 26) &amp; 0x3F; }\n        set { data = (data &amp; ~(0x3F &lt;&lt; 26)) | (value &amp; 0x3F) &lt;&lt; 26; }\n    }\n}\n</code></pre>\n\n<p>Surprisingly this last, handmade solution seems to be the most convenient, least convoluted, and the shortest one. That's of course only my personal preference.</p>\n"}, {'answer_id': 29326393, 'author': 'SunsetQuest', 'author_id': 2352507, 'author_profile': 'https://Stackoverflow.com/users/2352507', 'pm_score': 4, 'selected': False, 'text': "<p>One more based off of Zbyl's answer.  This one is a little easier to change around for me - I just have to adjust the sz0,sz1... and also make sure mask# and loc# are correct in the Set/Get blocks.</p>\n\n<p>Performance wise, it should be the same as they both resolved to 38 MSIL statements. (constants are resolved at compile time)</p>\n\n<pre><code>public struct MyStruct\n{\n    internal uint raw;\n\n    const int sz0 = 4, loc0 = 0,          mask0 = ((1 &lt;&lt; sz0) - 1) &lt;&lt; loc0;\n    const int sz1 = 4, loc1 = loc0 + sz0, mask1 = ((1 &lt;&lt; sz1) - 1) &lt;&lt; loc1;\n    const int sz2 = 4, loc2 = loc1 + sz1, mask2 = ((1 &lt;&lt; sz2) - 1) &lt;&lt; loc2;\n    const int sz3 = 4, loc3 = loc2 + sz2, mask3 = ((1 &lt;&lt; sz3) - 1) &lt;&lt; loc3;\n\n    public uint Item0\n    {\n        get { return (uint)(raw &amp; mask0) &gt;&gt; loc0; }\n        set { raw = (uint)(raw &amp; ~mask0 | (value &lt;&lt; loc0) &amp; mask0); }\n    }\n\n    public uint Item1\n    {\n        get { return (uint)(raw &amp; mask1) &gt;&gt; loc1; }\n        set { raw = (uint)(raw &amp; ~mask1 | (value &lt;&lt; loc1) &amp; mask1); }\n    }\n\n    public uint Item2\n    {\n        get { return (uint)(raw &amp; mask2) &gt;&gt; loc2; }\n        set { raw = (uint)(raw &amp; ~mask2 | (value &lt;&lt; loc2) &amp; mask2); }\n    }\n\n    public uint Item3\n    {\n        get { return (uint)((raw &amp; mask3) &gt;&gt; loc3); }\n        set { raw = (uint)(raw &amp; ~mask3 | (value &lt;&lt; loc3) &amp; mask3); }\n    }\n}\n</code></pre>\n"}, {'answer_id': 38189258, 'author': 'stalendp', 'author_id': 6053477, 'author_profile': 'https://Stackoverflow.com/users/6053477', 'pm_score': 2, 'selected': False, 'text': '<p>I wrote one, share it, may help someone:</p>\n\n<pre><code>[global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]\npublic sealed class BitInfoAttribute : Attribute {\n    byte length;\n    public BitInfoAttribute(byte length) {\n        this.length = length;\n    }\n    public byte Length { get { return length; } }\n}\n\npublic abstract class BitField {\n\n    public void parse&lt;T&gt;(T[] vals) {\n        analysis().parse(this, ArrayConverter.convert&lt;T, uint&gt;(vals));\n    }\n\n    public byte[] toArray() {\n        return ArrayConverter.convert&lt;uint, byte&gt;(analysis().toArray(this));\n    }\n\n    public T[] toArray&lt;T&gt;() {\n        return ArrayConverter.convert&lt;uint, T&gt;(analysis().toArray(this));\n    }\n\n    static Dictionary&lt;Type, BitTypeInfo&gt; bitInfoMap = new Dictionary&lt;Type, BitTypeInfo&gt;();\n    private BitTypeInfo analysis() {\n        Type type = this.GetType();\n        if (!bitInfoMap.ContainsKey(type)) {\n            List&lt;BitInfo&gt; infos = new List&lt;BitInfo&gt;();\n\n            byte dataIdx = 0, offset = 0;\n            foreach (System.Reflection.FieldInfo f in type.GetFields()) {\n                object[] attrs = f.GetCustomAttributes(typeof(BitInfoAttribute), false);\n                if (attrs.Length == 1) {\n                    byte bitLen = ((BitInfoAttribute)attrs[0]).Length;\n                    if (offset + bitLen &gt; 32) {\n                        dataIdx++;\n                        offset = 0;\n                    }\n                    infos.Add(new BitInfo(f, bitLen, dataIdx, offset));\n                    offset += bitLen;\n                }\n            }\n            bitInfoMap.Add(type, new BitTypeInfo(dataIdx + 1, infos.ToArray()));\n        }\n        return bitInfoMap[type];\n    }\n}\n\nclass BitTypeInfo {\n    public int dataLen { get; private set; }\n    public BitInfo[] bitInfos { get; private set; }\n\n    public BitTypeInfo(int _dataLen, BitInfo[] _bitInfos) {\n        dataLen = _dataLen;\n        bitInfos = _bitInfos;\n    }\n\n    public uint[] toArray&lt;T&gt;(T obj) {\n        uint[] datas = new uint[dataLen];\n        foreach (BitInfo bif in bitInfos) {\n            bif.encode(obj, datas);\n        }\n        return datas;\n    }\n\n    public void parse&lt;T&gt;(T obj, uint[] vals) {\n        foreach (BitInfo bif in bitInfos) {\n            bif.decode(obj, vals);\n        }\n    }\n}\n\nclass BitInfo {\n\n    private System.Reflection.FieldInfo field;\n    private uint mask;\n    private byte idx, offset, shiftA, shiftB;\n    private bool isUnsigned = false;\n\n    public BitInfo(System.Reflection.FieldInfo _field, byte _bitLen, byte _idx, byte _offset) {\n        field = _field;\n        mask = (uint)(((1 &lt;&lt; _bitLen) - 1) &lt;&lt; _offset);\n        idx = _idx;\n        offset = _offset;\n        shiftA = (byte)(32 - _offset - _bitLen);\n        shiftB = (byte)(32 - _bitLen);\n\n        if (_field.FieldType == typeof(bool)\n            || _field.FieldType == typeof(byte)\n            || _field.FieldType == typeof(char)\n            || _field.FieldType == typeof(uint)\n            || _field.FieldType == typeof(ulong)\n            || _field.FieldType == typeof(ushort)) {\n            isUnsigned = true;\n        }\n    }\n\n    public void encode(Object obj, uint[] datas) {\n        if (isUnsigned) {\n            uint val = (uint)Convert.ChangeType(field.GetValue(obj), typeof(uint));\n            datas[idx] |= ((uint)(val &lt;&lt; offset) &amp; mask);\n        } else {\n            int val = (int)Convert.ChangeType(field.GetValue(obj), typeof(int));\n            datas[idx] |= ((uint)(val &lt;&lt; offset) &amp; mask);\n        }\n    }\n\n    public void decode(Object obj, uint[] datas) {\n        if (isUnsigned) {\n            field.SetValue(obj, Convert.ChangeType((((uint)(datas[idx] &amp; mask)) &lt;&lt; shiftA) &gt;&gt; shiftB, field.FieldType));\n        } else {\n            field.SetValue(obj, Convert.ChangeType((((int)(datas[idx] &amp; mask)) &lt;&lt; shiftA) &gt;&gt; shiftB, field.FieldType));\n        }\n    }\n}\n\npublic class ArrayConverter {\n    public static T[] convert&lt;T&gt;(uint[] val) {\n        return convert&lt;uint, T&gt;(val);\n    }\n\n    public static T1[] convert&lt;T0, T1&gt;(T0[] val) {\n        T1[] rt = null;\n        // type is same or length is same\n        // refer to http://stackoverflow.com/questions/25759878/convert-byte-to-sbyte\n        if (typeof(T0) == typeof(T1)) { \n            rt = (T1[])(Array)val;\n        } else {\n            int len = Buffer.ByteLength(val);\n            int w = typeWidth&lt;T1&gt;();\n            if (w == 1) { // bool\n                rt = new T1[len * 8];\n            } else if (w == 8) {\n                rt = new T1[len];\n            } else { // w &gt; 8\n                int nn = w / 8;\n                int len2 = (len / nn) + ((len % nn) &gt; 0 ? 1 : 0);\n                rt = new T1[len2];\n            }\n\n            Buffer.BlockCopy(val, 0, rt, 0, len);\n        }\n        return rt;\n    }\n\n    public static string toBinary&lt;T&gt;(T[] vals) {\n        StringBuilder sb = new StringBuilder();\n        int width = typeWidth&lt;T&gt;();\n        int len = Buffer.ByteLength(vals);\n        for (int i = len-1; i &gt;=0; i--) {\n            sb.Append(Convert.ToString(Buffer.GetByte(vals, i), 2).PadLeft(8, \'0\')).Append(" ");\n        }\n        return sb.ToString();\n    }\n\n    private static int typeWidth&lt;T&gt;() {\n        int rt = 0;\n        if (typeof(T) == typeof(bool)) { // x\n            rt = 1;\n        } else if (typeof(T) == typeof(byte)) { // x\n            rt = 8;\n        } else if (typeof(T) == typeof(sbyte)) {\n            rt = 8;\n        } else if (typeof(T) == typeof(ushort)) { // x\n            rt = 16;\n        } else if (typeof(T) == typeof(short)) {\n            rt = 16;\n        } else if (typeof(T) == typeof(char)) {\n            rt = 16;\n        } else if (typeof(T) == typeof(uint)) { // x\n            rt = 32;\n        } else if (typeof(T) == typeof(int)) {\n            rt = 32;\n        } else if (typeof(T) == typeof(float)) {\n            rt = 32;\n        } else if (typeof(T) == typeof(ulong)) { // x\n            rt = 64;\n        } else if (typeof(T) == typeof(long)) {\n            rt = 64;\n        } else if (typeof(T) == typeof(double)) {\n            rt = 64;\n        } else {\n            throw new Exception("Unsupport type : " + typeof(T).Name);\n        }\n        return rt;\n    }\n}\n</code></pre>\n\n<p>and the usage: </p>\n\n<pre><code>class MyTest01 : BitField {\n    [BitInfo(3)]\n    public bool d0;\n    [BitInfo(3)]\n    public short d1;\n    [BitInfo(3)]\n    public int d2;\n    [BitInfo(3)]\n    public int d3;\n    [BitInfo(3)]\n    public int d4;\n    [BitInfo(3)]\n    public int d5;\n\n    public MyTest01(bool _d0, short _d1, int _d2, int _d3, int _d4, int _d5) {\n        d0 = _d0;\n        d1 = _d1;\n        d2 = _d2;\n        d3 = _d3;\n        d4 = _d4;\n        d5 = _d5;\n    }\n\n    public MyTest01(byte[] datas) {\n        parse(datas);\n    }\n\n    public new string ToString() {\n        return string.Format("d0: {0}, d1: {1}, d2: {2}, d3: {3}, d4: {4}, d5: {5} \\r\\nbinary =&gt; {6}",\n            d0, d1, d2, d3, d4, d5, ArrayConverter.toBinary(toArray()));\n    }\n};\n\nclass MyTest02 : BitField {\n    [BitInfo(5)]\n    public bool val0;\n    [BitInfo(5)]\n    public byte val1;\n    [BitInfo(15)]\n    public uint val2;\n    [BitInfo(15)]\n    public float val3;\n    [BitInfo(15)]\n    public int val4;\n    [BitInfo(15)]\n    public int val5;\n    [BitInfo(15)]\n    public int val6;\n\n    public MyTest02(bool v0, byte v1, uint v2, float v3, int v4, int v5, int v6) {\n        val0 = v0;\n        val1 = v1;\n        val2 = v2;\n        val3 = v3;\n        val4 = v4;\n        val5 = v5;\n        val6 = v6;\n    }\n\n    public MyTest02(byte[] datas) {\n        parse(datas);\n    }\n\n    public new string ToString() {\n        return string.Format("val0: {0}, val1: {1}, val2: {2}, val3: {3}, val4: {4}, val5: {5}, val6: {6}\\r\\nbinary =&gt; {7}",\n            val0, val1, val2, val3, val4, val5, val6, ArrayConverter.toBinary(toArray()));\n    }\n}\n\npublic class MainClass {\n\n    public static void Main(string[] args) {\n        MyTest01 p = new MyTest01(false, 1, 2, 3, -1, -2);\n        Debug.Log("P:: " + p.ToString());\n        MyTest01 p2 = new MyTest01(p.toArray());\n        Debug.Log("P2:: " + p2.ToString());\n\n        MyTest02 t = new MyTest02(true, 1, 12, -1.3f, 4, -5, 100);\n        Debug.Log("t:: " + t.ToString());\n        MyTest02 t2 = new MyTest02(t.toArray());\n        Debug.Log("t:: " + t.ToString());\n\n        Console.Read();\n        return;\n    }\n}\n</code></pre>\n'}, {'answer_id': 55834344, 'author': 'Vito Marolda', 'author_id': 6681740, 'author_profile': 'https://Stackoverflow.com/users/6681740', 'pm_score': 3, 'selected': False, 'text': '<p>I find myself quite comfortable with these helper functions:</p>\n\n<pre><code>uint SetBits(uint word, uint value, int pos, int size)\n{\n    uint mask = ((((uint)1) &lt;&lt; size) - 1) &lt;&lt; pos;\n    word &amp;= ~mask; //resettiamo le posizioni\n    word |= (value &lt;&lt; pos) &amp; mask;\n    return word;\n}\n\nuint ReadBits(uint word, int pos, int size)\n{\n    uint mask = ((((uint)1) &lt;&lt; size) - 1) &lt;&lt; pos;\n    return (word &amp; mask) &gt;&gt; pos;\n}\n</code></pre>\n\n<p>then:</p>\n\n<pre><code>uint the_word;\n\npublic uint Itemx\n{\n    get { return ReadBits(the_word, 5, 2); }\n    set { the_word = SetBits(the_word, value, 5, 2) }\n}\n</code></pre>\n'}, {'answer_id': 68870859, 'author': 'scobi', 'author_id': 14582, 'author_profile': 'https://Stackoverflow.com/users/14582', 'pm_score': 0, 'selected': False, 'text': '<p>I wrote one this morning with T4. :) Same example as Zbyl, though I threw in a bit of uint sizing fun. This is just a first pass, it could obviously use a little error checking. Also the bitFields spec array would be nicer in a separate file, maybe a .ttinclude, or a json/yaml..</p>\n<pre><code>=== BitFields.tt ===\n\n&lt;#@ template language=&quot;C#&quot; #&gt;\n&lt;#@ assembly name=&quot;System.Core&quot; #&gt;\n&lt;#@ import namespace=&quot;System.Linq&quot; #&gt;\n\n&lt;#\nvar bitFields = new[]\n{\n    new\n    {\n        Name = &quot;rcSpan2&quot;, Fields = new[] { (&quot;smin&quot;, 13), (&quot;smax&quot;, 13), (&quot;area&quot;, 6) },\n    },  \n};\n\nforeach (var bitField in bitFields)\n{\n    static string getType(int size) =&gt;\n        size switch\n        {\n            &gt; 32 =&gt; &quot;ulong&quot;,\n            &gt; 16 =&gt; &quot;uint&quot;,\n            &gt; 8 =&gt; &quot;ushort&quot;,\n            _ =&gt; &quot;byte&quot;,\n        };\n\n    var bitFieldType = getType(bitField.Fields.Sum(f =&gt; f.Item2)); \n#&gt;\npublic struct &lt;#=bitField.Name#&gt;\n{\n    &lt;#=bitFieldType#&gt; _bitfield;\n\n&lt;#\nvar offset = 0;\nforeach (var (fieldName, fieldSize) in bitField.Fields)\n{\n    var fieldType = getType(fieldSize);\n    var fieldMask = $&quot;0x{((1UL&lt;&lt;fieldSize)-1):X}U&quot;;\n#&gt;\n    public &lt;#=fieldType#&gt; &lt;#=fieldName#&gt; // : &lt;#=fieldSize#&gt;\n    {\n        get =&gt; (&lt;#=fieldType#&gt;)(&lt;#=offset &gt; 0 ? $&quot;(_bitfield &gt;&gt; {offset})&quot; : &quot;_bitfield&quot;#&gt; &amp; &lt;#=fieldMask#&gt;);\n        set =&gt; _bitfield = (&lt;#=bitFieldType#&gt;)((_bitfield &amp; ~((&lt;#=bitFieldType#&gt;)&lt;#=fieldMask#&gt; &lt;&lt; &lt;#=offset#&gt;)) | ((&lt;#=bitFieldType#&gt;)(value &amp; &lt;#=fieldMask#&gt;) &lt;&lt; &lt;#=offset#&gt;));\n    }  \n&lt;#\n    offset += fieldSize;\n}\n#&gt;\n}\n\n&lt;#}#&gt;\n\n=== BitFields.cs === (generated)\n\npublic struct rcSpan2\n{\n    uint _bitfield;\n\n    public ushort smin // : 13\n    {\n        get =&gt; (ushort)(_bitfield &amp; 0x1FFFU);\n        set =&gt; _bitfield = (uint)((_bitfield &amp; ~((uint)0x1FFFU &lt;&lt; 0)) | ((uint)(value &amp; 0x1FFFU) &lt;&lt; 0));\n    }  \n    public ushort smax // : 13\n    {\n        get =&gt; (ushort)((_bitfield &gt;&gt; 13) &amp; 0x1FFFU);\n        set =&gt; _bitfield = (uint)((_bitfield &amp; ~((uint)0x1FFFU &lt;&lt; 13)) | ((uint)(value &amp; 0x1FFFU) &lt;&lt; 13));\n    }  \n    public byte area // : 6\n    {\n        get =&gt; (byte)((_bitfield &gt;&gt; 26) &amp; 0x3FU);\n        set =&gt; _bitfield = (uint)((_bitfield &amp; ~((uint)0x3FU &lt;&lt; 26)) | ((uint)(value &amp; 0x3FU) &lt;&lt; 26));\n    }  \n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/14464', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1006/']