在C#中存储布尔数据时,如何节省空间

问题描述

|| 我需要在Windows Azure中存储布尔数据。我想让这些占用的空间尽可能小。我所拥有的是约15个字段,其值为true或false。
field_1 = true;
field_2 = true;
field_a = false;
field_xx = true;
我有一个想法,我可以接受这些,将true和false分别转换为1和0,然后将其存储为类似于1101的字符串。是否有一种简单的方法可以进行编码,然后在取出数据时取消编码?请注意,字段名称都是不同的,因此我不能使用花哨的for循环来遍历字段名称。     

解决方法

        
int bits = (field_1 ? 1 : 0) | (field_2 ? 2 : 0) | (field_3 ? 4 : 0) | (field_4 ? 8 : 0) | ...

field_1 = (bits & 1) != 0;
field_2 = (bits & 2) != 0;
field_3 = (bits & 4) != 0;
field_4 = (bits & 8) != 0;
...
    ,        我想您甚至都无法想象我会对这种以任何方式,形状或形式提供帮助的怀疑态度。 15个布尔值实际上什么都不是。 现在,如果您坚持走这条路,最好的方法是将它们存储为单个
int
,并使用
&
读出它们,并使用
|
写回它们。     ,        考虑具有[Flags]属性的枚举
[Flags]
public enum Values
{
  Field1 = 1,Field2 = 2,Field3 = 4,Field4 = 8
}    
Values obj = Field1 | Field2;
obj.HasValue(Field1); //true
obj.HasValue(Field3); //false
int storage = (int)obj;// 3
    ,        不要打扰您正在使用布尔值,布尔值已经足够小(对于单个值)(我相信是1个字节)。而且,您可能能够节省的少量空间不值得增加代码的复杂性以及开发时间。 还有一些想法:思考如何使用这样的构造。当前,如果您查看
field_1
并看到一个值
true
,则不必深入研究实现即可得出实际值。但是,假设您具有以下字符串:\“ 100101011011010 \”(或
19162
的整数值,这样会更有效)。 ѭ6是对还是错?从本质上来说,这不是显而易见的-您需要查找实现。当您需要在线下支持更多字段时会发生什么?坚持自己拥有的东西,将为您节省很多心痛。     ,        您可以使用BitArray将布尔值打包为
int
BitArray b = new BitArray(new bool[] { field_1,field_2,...,field_xy });
int[] buffer = new int[1];
b.CopyTo(buffer,0);
int data = buffer[0];
您可以使用
byte
int
数组。
byte
最多可容纳8个布尔值,an2ѭ最多可容纳32个布尔值。要容纳最多16个布尔值,您可以使用具有两个字节的字节数组,也可以使用单个
int
,具体取决于数组的开销还是数组中未使用的位。
int
占用更多空间。您也可以使用
BitConverter
类将两个字节的数组转换为
short
。 要取回布尔值,可以从数组
byte
int
创建一个BitArray:
BitArray b = new BitArray(new int[] { data });
field_1 = b[0];
field_2 = b[1];
...
field_xy = b[14];
    ,        将它们存储为字符将占用每个值8或16位。我将使用位移操作将它们打包到可用的最长的无符号整数数组中。     ,        在以下位置有一篇很棒的文章: http://blog.millermedeiros.com/2010/12/using-integers-to-store-multiple-boolean-values/     ,        您可以使用int并使用xor http://www.dotnetperls.com/xor 我看到一个大约15年前做到这一点的项目。但是最终它在系统中限制为32个角色(使用32位数字)。该产品今天不存在:) 所以不要这样做,将值存储在数组或单独的字段中。     ,        您可以将Enum与flags属性一起使用。您说您有15个字段。所以你可以尝试使用类似 [标志] 枚举Fieldvals { Field1,Field2,... } 请参阅http://msdn.microsoft.com/zh-cn/library/system.flagsattribute.aspx以获得指导     ,        签出BitArray类,它应该完全满足您的需求。 例:
BitArray bits = new BitArray
(
    new bool[]
    {
        false,true,false,false
    }
);

short values = 0;

for( int index = 0; index < bits.Length; index++ )
{
    if( bits[ index ] )
        values |= ( short )( values | ( 1 << index ) ); 
}

Console.WriteLine( Convert.ToString( values,2 ) );
现在,您在单个16位字段中存储了15个布尔变量。     ,        您可以将标志存储为整数值。以下是一些帮助方法来实现此目的:
// Sets the given bit position in the UInt32 to the specified boolean value 
public static UInt32 Set(UInt32 u,int position,bool newBitValue)
{
    UInt32 mask = (UInt32)(1 << position);

    if (newBitValue)
        return (u | mask)
    else
        return (u & ~mask);
}

// Gets a bit value from the supplied UInt32
public static bool Get(UInt32 u,int position)
{
    return ((u & (UInt32)(1 << position)) != 0);
}