位元欄位是將多個布林值打包到單一位元組或字中的有用方法,允許有效儲存和操作標誌和其他類似布爾的數據。在 C 中,位元欄位是使用 struct 關鍵字定義的,後面跟著一系列位元欄位成員,每個成員指定為該成員分配的位數。
在此 StackOverflow 問題中,使用者詢問有關一種在 C# 中實現位元欄位的方法,可以使用結構解引用點運算子來存取位元。問題源自於需要處理具有位元欄位成員的多個結構。
一個建議的解決方案是利用屬性和轉換類別將適當的屬性結構轉換為位元字段基元。這些屬性用於指定每個位元字段成員的長度,轉換類別負責將帶註釋的結構轉換為適當的位元字段表示形式。
以下是此類實現的範例:
using System; namespace BitfieldTest { [global::System.AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] sealed class BitfieldLengthAttribute : Attribute { uint length; public BitfieldLengthAttribute(uint length) { this.length = length; } public uint Length { get { return length; } } } static class PrimitiveConversion { public static long ToLong<T>(T t) where T : struct { long r = 0; int offset = 0; // For every field suitably attributed with a BitfieldLength foreach (System.Reflection.FieldInfo f in t.GetType().GetFields()) { object[] attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false); if (attrs.Length == 1) { uint fieldLength = ((BitfieldLengthAttribute)attrs[0]).Length; // Calculate a bitmask of the desired length long mask = 0; for (int i = 0; i < fieldLength; i++) mask |= 1 << i; r |= ((UInt32)f.GetValue(t) & mask) << offset; offset += (int)fieldLength; } } return r; } } struct PESHeader { [BitfieldLength(2)] public uint reserved; [BitfieldLength(2)] public uint scrambling_control; [BitfieldLength(1)] public uint priority; [BitfieldLength(1)] public uint data_alignment_indicator; [BitfieldLength(1)] public uint copyright; [BitfieldLength(1)] public uint original_or_copy; }; public class MainClass { public static void Main(string[] args) { PESHeader p = new PESHeader(); p.reserved = 3; p.scrambling_control = 2; p.data_alignment_indicator = 1; long l = PrimitiveConversion.ToLong(p); for (int i = 63; i >= 0; i--) { Console.Write(((l & (1l << i)) > 0) ? "1" : "0"); } Console.WriteLine(); return; } } }
這種方法提高了程式碼可讀性並加快了編寫速度,使其能夠更有效地處理具有位元欄位成員的大量結構。
以上是如何使用屬性和結構體解引用在 C# 中高效實現位元字段?的詳細內容。更多資訊請關注PHP中文網其他相關文章!