PropertyBitPack: Упаковка свойств в поля

от автора

Доброго времени суток дорогие читатели, короче в декабре 24 года разбирался в коде рослин, и жутко понравилось то как команда рослин уместила 12 булевых свойств и одно байтовое, в единственное ushort поле. Ну и на основе этого быстренько за месяц создал простенькую библиотеку, авось людям это будет нужно.

Упаковка булевых значений

public partial class BitPackedBools {     [BitField]     public partial bool Bool1 { get; set; }      [BitField]     public partial bool Bool2 { get; set; }      [BitField]     public partial bool Bool3 { get; set; }      [BitField]     public partial bool Bool4 { get; set; } }

В этом случае будет сгенерировано 1 байтовое поле, где первые 4 бита используют булевые свойства, имя поля будет равно свойствам которое использует поле.

Сгенерированный код
partial class BitPackedBools {     private byte _Bool1__Bool2__Bool3__Bool4__;     public partial bool Bool1     {         get         {             return ((this._Bool1__Bool2__Bool3__Bool4__ >> 0) & (1)) == 1;         }         set         {             this._Bool1__Bool2__Bool3__Bool4__ = (byte)(value ? ((this._Bool1__Bool2__Bool3__Bool4__) | (((1 << 1) - 1) << 0)) : (this._Bool1__Bool2__Bool3__Bool4__ & ~(((1 << 1) - 1) << 0)));         }     }      public partial bool Bool2     {         get         {             return ((this._Bool1__Bool2__Bool3__Bool4__ >> 1) & (1)) == 1;         }         set         {             this._Bool1__Bool2__Bool3__Bool4__ = (byte)(value ? ((this._Bool1__Bool2__Bool3__Bool4__) | (((1 << 1) - 1) << 1)) : (this._Bool1__Bool2__Bool3__Bool4__ & ~(((1 << 1) - 1) << 1)));         }     }      public partial bool Bool3     {         get         {             return ((this._Bool1__Bool2__Bool3__Bool4__ >> 2) & (1)) == 1;         }         set         {             this._Bool1__Bool2__Bool3__Bool4__ = (byte)(value ? ((this._Bool1__Bool2__Bool3__Bool4__) | (((1 << 1) - 1) << 2)) : (this._Bool1__Bool2__Bool3__Bool4__ & ~(((1 << 1) - 1) << 2)));         }     }      public partial bool Bool4     {         get         {             return ((this._Bool1__Bool2__Bool3__Bool4__ >> 3) & (1)) == 1;         }         set         {             this._Bool1__Bool2__Bool3__Bool4__ = (byte)(value ? ((this._Bool1__Bool2__Bool3__Bool4__) | (((1 << 1) - 1) << 3)) : (this._Bool1__Bool2__Bool3__Bool4__ & ~(((1 << 1) - 1) << 3)));         }     } }

Флаги + SloutCount

Давайте попробуем сделать имитацию NodeFlagsAndSlotCount

public partial class NodeFlagsAndSlotCount {     [BitField]     public partial bool IsNotMissing { get; set; }      [BitField]     public partial bool HasAnnotationsDirectly { get; set; }      [BitField]     public partial bool FactoryContextIsInAsync { get; set; }      [BitField]     public partial bool FactoryContextIsInQuery { get; set; }      [BitField]     public partial bool FactoryContextIsInFieldKeywordContext { get; set; }      [BitField]     public partial bool ContainsAnnotations { get; set; }      [BitField]     public partial bool ContainsAttributes { get; set; }      [BitField]     public partial bool ContainsDiagnostics { get; set; }      [BitField]     public partial bool ContainsDirectives { get; set; }      [BitField]     public partial bool ContainsSkippedText { get; set; }      [BitField]     public partial bool ContainsStructuredTrivia { get; set; }      [BitField]     public partial bool ExtraFlag { get; set; }      [ExtendedBitField(BitsCount = 4, GetterLargeSizeValueName = nameof(GetLargeSlotCount))]     public partial int SlotCount { get; set; }      public virtual int GetLargeSlotCount() => 255; }

Прежде чем покажу что сгенерировалась, расскажу немного про атрибут ExtendedBitField.

  • Он наследуется от BitField

  • Если вдруг значение SlotCount больше, чем помещается в 4 бита, то геттер свойства вызывает GetterLargeSizeValueName

  • Использование nameof обязательно, без него генератор не будет работать

GetterLargeSizeValueName может быть:

  • Методом, что обязательно должен возвращать тот же тип что и свойство

  • Другим свойством

  • Полем

Вот сгенерированный код:
partial class NodeFlagsAndSlotCount {     private ushort _IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__;     public partial bool IsNotMissing     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 0) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 0)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 0)));         }     }      public partial bool HasAnnotationsDirectly     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 1) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 1)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 1)));         }     }      public partial bool FactoryContextIsInAsync     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 2) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 2)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 2)));         }     }      public partial bool FactoryContextIsInQuery     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 3) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 3)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 3)));         }     }      public partial bool FactoryContextIsInFieldKeywordContext     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 4) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 4)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 4)));         }     }      public partial bool ContainsAnnotations     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 5) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 5)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 5)));         }     }      public partial bool ContainsAttributes     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 6) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 6)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 6)));         }     }      public partial bool ContainsDiagnostics     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 7) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 7)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 7)));         }     }      public partial bool ContainsDirectives     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 8) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 8)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 8)));         }     }      public partial bool ContainsSkippedText     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 9) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 9)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 9)));         }     }      public partial bool ContainsStructuredTrivia     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 10) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 10)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 10)));         }     }      public partial bool ExtraFlag     {         get         {             return ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 11) & (1)) == 1;         }          set         {             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)(value ? ((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__) | (((1 << 1) - 1) << 11)) : (this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 1) - 1) << 11)));         }     }      public partial int SlotCount     {         get         {             const int maxValue_ = (1 << 4) - 1;             int value_ = (int)((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ >> 12) & ((1 << 4) - 1));             if (value_ == maxValue_)             {                 return GetLargeSlotCount();             }              return value_;         }          set         {             const ushort maxValue_ = (1 << 4) - 1;             var clamped_ = global::System.Math.Min((ushort)(value), maxValue_);             this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ = (ushort)((this._IsNotMissing__HasAnnotationsDirectly__FactoryContextIsInAsync__FactoryContextIsInQuery__FactoryContextIsInFieldKeywordContext__ContainsAnnotations__ContainsAttributes__ContainsDiagnostics__ContainsDirectives__ContainsSkippedText__ContainsStructuredTrivia__ExtraFlag__SlotCount__ & ~(((1 << 4) - 1) << 12)) | ((clamped_ & ((1 << 4) - 1)) << 12));         }     } }

Однако GreenNode по концепции своей иммутабельны, давайте и это реализуем:

public partial class NodeFlagsAndSlotCount {     private readonly ushort _data;      [BitField(FieldName = nameof(_data))]     public partial bool IsNotMissing { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool HasAnnotationsDirectly { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool FactoryContextIsInAsync { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool FactoryContextIsInQuery { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool FactoryContextIsInFieldKeywordContext { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool ContainsAnnotations { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool ContainsAttributes { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool ContainsDiagnostics { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool ContainsDirectives { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool ContainsSkippedText { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool ContainsStructuredTrivia { get; init; }      [BitField(FieldName = nameof(_data))]     public partial bool ExtraFlag { get; init; }      [ExtendedBitField(BitsCount = 4, GetterLargeSizeValueName = nameof(GetLargeSlotCount), FieldName = nameof(_data))]     public partial int SlotCount { get; init; }      public virtual int GetLargeSlotCount() => 255; } 

Вуаля, позвольте заметить что FieldName принимает строку, но тогда генератор создаст поле с таким именем, а если хотите что бы свойства использовали уже существующее поле, то ссылайтесь на него через nameof

Сгенерированный код
partial class NodeFlagsAndSlotCount {     public partial bool IsNotMissing     {         get         {             return ((this._data >> 0) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 0)) : (this._data & ~(((1 << 1) - 1) << 0)));         }     }      public partial bool HasAnnotationsDirectly     {         get         {             return ((this._data >> 1) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 1)) : (this._data & ~(((1 << 1) - 1) << 1)));         }     }      public partial bool FactoryContextIsInAsync     {         get         {             return ((this._data >> 2) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 2)) : (this._data & ~(((1 << 1) - 1) << 2)));         }     }      public partial bool FactoryContextIsInQuery     {         get         {             return ((this._data >> 3) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 3)) : (this._data & ~(((1 << 1) - 1) << 3)));         }     }      public partial bool FactoryContextIsInFieldKeywordContext     {         get         {             return ((this._data >> 4) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 4)) : (this._data & ~(((1 << 1) - 1) << 4)));         }     }      public partial bool ContainsAnnotations     {         get         {             return ((this._data >> 5) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 5)) : (this._data & ~(((1 << 1) - 1) << 5)));         }     }      public partial bool ContainsAttributes     {         get         {             return ((this._data >> 6) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 6)) : (this._data & ~(((1 << 1) - 1) << 6)));         }     }      public partial bool ContainsDiagnostics     {         get         {             return ((this._data >> 7) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 7)) : (this._data & ~(((1 << 1) - 1) << 7)));         }     }      public partial bool ContainsDirectives     {         get         {             return ((this._data >> 8) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 8)) : (this._data & ~(((1 << 1) - 1) << 8)));         }     }      public partial bool ContainsSkippedText     {         get         {             return ((this._data >> 9) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 9)) : (this._data & ~(((1 << 1) - 1) << 9)));         }     }      public partial bool ContainsStructuredTrivia     {         get         {             return ((this._data >> 10) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 10)) : (this._data & ~(((1 << 1) - 1) << 10)));         }     }      public partial bool ExtraFlag     {         get         {             return ((this._data >> 11) & (1)) == 1;         }          init         {             this._data = (ushort)(value ? ((this._data) | (((1 << 1) - 1) << 11)) : (this._data & ~(((1 << 1) - 1) << 11)));         }     }      public partial int SlotCount     {         get         {             const int maxValue_ = (1 << 4) - 1;             int value_ = (int)((this._data >> 12) & ((1 << 4) - 1));             if (value_ == maxValue_)             {                 return GetLargeSlotCount();             }              return value_;         }          init         {             const ushort maxValue_ = (1 << 4) - 1;             var clamped_ = global::System.Math.Min((ushort)(value), maxValue_);             this._data = (ushort)((this._data & ~(((1 << 4) - 1) << 12)) | ((clamped_ & ((1 << 4) - 1)) << 12));         }     } }

Есть и другие фишки в библиотеке PropertyBitPack.

Заключение

Ну, по итогу это библиотека, ради библиотеки. Если вдруг пригодиться, скажите как пригодилась ну и поставьте звёздочку в гитхабе.


ссылка на оригинал статьи https://habr.com/ru/articles/885116/