TheDeveloperBlog.com


C# Nullable Bool

Nullable Bool. Are nullable bools efficient? These enable us to represent a null, true and false value in a single variable. But we want to know if this is an efficient representation of a three-value variable.


Example. Let's get started with the nullable bool example. To use a nullable bool, use the type "bool?" with the trailing question mark. This is a struct that contains a bool. The "bool?" can be set to null, true and false.

NullTrue, False

Also: The program shows that each "bool?" occupies 2 bytes in memory. It has an extra byte of overhead beyond a regular bool.

Bool
C# program that uses nullable bool

using System;

class Program
{
    static void Main()
    {
	bool? tristate = null;
	tristate = true;
	tristate = false;

	Console.WriteLine(tristate);

	long m1 = GC.GetTotalMemory(false);
	bool?[] b1 = new bool?[100000];
	long m2 = GC.GetTotalMemory(false);
	b1[0] = false;

	Console.WriteLine("{0} bytes per bool?", (m2 - m1) / 100000);
    }
}

Output

False
2 bytes per bool?


Tristate enum. Next, we consider a tristate enum, which can be implemented with a byte backing store. Notice how the semicolon syntax ": byte" is used after the enum type declaration. It can be set to Tristate.Null, Tristate.True and Tristate.False.

Tip: Unlike the nullable bool, all three values can be represented in one byte of storage.

EnumByte
C# program that uses Tristate byte enum

using System;

class Program
{
    enum Tristate : byte
    {
	Null = 0,
	True = 1,
	False = 2
    }

    static void Main()
    {
	Tristate tristate = Tristate.Null;
	tristate = Tristate.True;
	tristate = Tristate.False;

	Console.WriteLine(tristate);

	long m1 = GC.GetTotalMemory(false);
	Tristate[] b1 = new Tristate[100000];
	long m2 = GC.GetTotalMemory(false);
	b1[0] = Tristate.False;

	Console.WriteLine("{0} byte(s) per Tristate", (m2 - m1) / 100000);
    }
}

Output

False
1 byte(s) per Tristate


Summary. Nullable bools can represent three values: null, false and true. But as we saw here, a custom enum type that uses a byte backing store can more efficiently represent these three values. In type safety the approaches are equally effective.

However: The enum type avoids the overhead associated with wrapping a value type in a generic struct.

Generic Class