ExtendedBitFieldAttribute

ExtendedBitFieldAttribute extends the functionality of BitFieldAttribute. It provides the same features as BitFieldAttribute but adds support for handling values that exceed the allocated bit size.

What is ExtendedBitFieldAttribute?​

✅ ExtendedBitFieldAttribute inherits from BitFieldAttribute.
✅ Supports bit-packing, custom bit sizes, and field name customization like BitFieldAttribute.
✅ If a value exceeds the specified bit size, the property getter calls an alternative source (method, property, or field).
✅ The alternative source is specified using GetterLargeSizeValueName.

Example: Handling Large Values​

public partial class ExtendedBitFieldExample
{
    public const int BitsCountSlotCountProperty = 11;

    [ExtendedBitField(BitsCount = BitsCountSlotCountProperty, GetterLargeSizeValueName = nameof(GetLargeSlotCount))]
    public partial int SlotCount { get; internal set; }

    [BitField(BitsCount = BitsCountSlotCountProperty)]
    public partial ushort SlotCount2 { get; internal set; }

    [ExtendedBitField(BitsCount = BitsCountSlotCountProperty, GetterLargeSizeValueName = nameof(GetLargeSlotCount))]
    public partial int SlotCount3 { get; internal set; }

    [ExtendedBitField(BitsCount = BitsCountSlotCountProperty, GetterLargeSizeValueName = nameof(GetLargeSlotCount))]
    public partial int SlotCount4 { get; internal set; }

    [ExtendedBitField(BitsCount = BitsCountSlotCountProperty, GetterLargeSizeValueName = nameof(GetLargeSlotCount))]
    public partial int SlotCount5 { get; internal set; }

    public static int GetLargeSlotCount(int a = 6)
    {
        return ((int)Math.Pow(2, 11)) + 123 * a;
    }
}

How Does It Work?​

  1. SlotCount is allocated 11 bits.
  2. If SlotCount is less than 2047 (2^11 - 1), the value is stored within the bit-packed field.
  3. If SlotCount exceeds 2047, the getter calls GetLargeSlotCount().

Generated Code​

partial class ExtendedBitFieldExample
{
    private ulong _SlotCount__SlotCount2__SlotCount3__SlotCount4__SlotCount5__;

    public partial int SlotCount
    {
        get
        {
            const int maxValue_ = (1 << 11) - 1;
            int value_ = (int)((this._SlotCount__SlotCount2__SlotCount3__SlotCount4__SlotCount5__ >> 0) & ((1UL << 11) - 1));
            if (value_ == maxValue_)
            {
                return GetLargeSlotCount();
            }
            return value_;
        }
        internal set
        {
            const ulong maxValue_ = (1UL << 11) - 1;
            var clamped_ = global::System.Math.Min((ulong)(value), maxValue_);
            this._SlotCount__SlotCount2__SlotCount3__SlotCount4__SlotCount5__ = (this._SlotCount__SlotCount2__SlotCount3__SlotCount4__SlotCount5__ & ~(((1UL << 11) - 1) << 0)) 
                | ((clamped_ & ((1UL << 11) - 1)) << 0);
        }
    }
}

GetterLargeSizeValueName​

The GetterLargeSizeValueName parameter specifies what should be used when the value exceeds the allocated bit size.

Valid Options​

✅ Method (must return the same type as the property)
✅ Another property
✅ A field

Example: Using Another Property​

public partial class AlternativeGetterExample
{
    [ExtendedBitField(BitsCount = 6, GetterLargeSizeValueName = nameof(FullValue))]
    public partial int ShortValue { get; set; }

    public int FullValue => 9999;
}

If ShortValue exceeds 2^6 = 64, the getter returns FullValue instead.


Important Notes​

⚠ Using nameof() is mandatory. The generator will not work without it.
⚠ If GetterLargeSizeValueName is missing, the generator will produce a compilation error.
⚠ The getter method must return the same type as the bit-packed property.

📖 Next: ReadOnly BitFields →