在C#中将字段声明为位(作为单个位,而不是字节倍数)

本文关键字:字节 单个位 字段 声明 | 更新日期: 2023-09-27 18:00:06

Joseph Albahari和Ben Albahari(O’Reilly)的《坚果壳中的C#6.0》。

版权所有2016 Joseph Albahari和Ben Albahari,978-1-491-92706-9。

在第312页介绍了BitArrays作为.NET提供的Collection类型之一:

BitArray

BitArray是压缩布尔值的动态大小集合。它比简单的bool数组和bool的泛型列表,因为它只为每个值使用一个位,而bool类型在其他情况下为每个值占用一个字节。

当您只对二进制值感兴趣时,可以声明一组位而不是使用字节,这很好,但声明一个位字段呢?

类似:

public class X
{
    public [bit-type] MyBit {get; set;}
}

.NET不支持它?

关于这个话题的现有帖子谈到了最终在字节变量中设置单个位。我在问,一旦.NET考虑支持在集合中使用位变量,它是否也支持声明非集合这样的变量。

在C#中将字段声明为位(作为单个位,而不是字节倍数)

所以您的问题是.NET是否支持这一点。答案是否定的。

为什么?从根本上说,拥有这样的功能是可能的。但需求确实很低。最好将开发人员的时间投入到其他地方。

如果你想利用低于字节粒度的内存,你需要自己构建。BitArray不是运行时固有的。它操纵一些更大类型的比特(我认为它是基于int的)。你也可以做同样的事情。

BitVector32是一个内置结构,您可以使用它单独寻址32位。

如您在.Net参考中所见,BitArray在内部将值存储在intArray

public BitArray(int length, bool defaultValue) {
    ...
    m_array = new int[GetArrayLength(length, BitsPerInt32)];
    m_length = length;
    int fillValue = defaultValue ? unchecked(((int)0xffffffff)) : 0;
    for (int i = 0; i < m_array.Length; i++) {
        m_array[i] = fillValue;
    }
    _version = 0;
}

因此,使用BitArray分配的最少的东西已经是引用的整个int,如果你在其中存储数据,则会更多。这也是有道理的,因为用于寻址任何内容的内存已经在数据字中了。根据体系结构的不同,它们至少有4个字节长。

当然,你可以为一个位定义一个自己的类型来存储,但这也需要至少一个字节-如果不是一个完整的字,也需要一个字节,因为它是一个引用类型。内存是由操作系统根据内存地址分配给程序的,内存地址通常是字节,所以任何少的都不完全有用。

它需要大量的二进制值来存储,甚至可以弥补最初使用类型时已经损失的空间,因此这种存储位技术的唯一真正有用的应用是当你有很多二进制值时,这样你就可以从8:1的内存比例中获利。