Veverke
Veverke

Reputation: 11358

Declaring a field as a bit (as a single bit, as opposed to a byte multiple) in C#

C# 6.0 in a Nutshell by Joseph Albahari and Ben Albahari (O’Reilly).

Copyright 2016 Joseph Albahari and Ben Albahari, 978-1-491-92706-9.

introduces, at page 312, BitArrays as one of the Collection types .NET provides:

BitArray

A BitArray is a dynamically sized collection of compacted bool values. It is more memory-efficient than both a simple array of bool and a generic List of bool, because it uses only one bit for each value, whereas the bool type otherwise occupies one byte for each value.

It's nice to have the possibility of declaring a collection of bits instead of working with bytes when you are interested in binary values only, but what about declaring a single bit field ?

like:

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

.NET does not support it ?

The existent posts on that touch the topic talk about setting individual bits within, ultimately, a byte variable. I am asking if, once .NET thought of supporting working with bit variables, in a collection, if it also supports declaring a non-collection such variable.

Upvotes: 3

Views: 188

Answers (2)

usr
usr

Reputation: 171178

So your question is whether .NET supports this or not. The answer is no.

Why? It's fundamentally possible to have such a feature. But the demand is really low. It's better to invest the developer time elsewhere.

If you want to make use of memory below the byte granularity you will need to build this yourself. BitArray is not intrinsic to the runtime. It manipulates the bits of some bigger type (I think it's int-based). You can do the same thing.

BitVector32 is a built-in struct that you can use to individually address 32 bits.

Upvotes: 3

Adwaenyth
Adwaenyth

Reputation: 2110

As you can see in the .Net reference, BitArray internally stores the values within an Array of int

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;
}

So the least thing that gets allocated with a BitArray is already an entire int for the reference and even more if you store data in it. This also makes sense since the memory the used for addressing anything is already in data words. Those are - depending on the architecture - at least 4 bytes long already.

You can of course define an own type for a single Bit to store, but this will also take at least a byte - if not even a complete word and a byte due to being a reference type - to do so. Memory is allocated to a program by the OS in terms of memory addresses, which usually address bytes, so anything less is not entirely useful.

It takes a lot of binary values to store, to even make up for the space already lost by using the type in the first place, so the only really useful application of this technique of storing bits is when you've got lots of them, so that you can profit of the 8:1 memory ratio.

Upvotes: 1

Related Questions