C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
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.
Also: The program shows that each "bool?" occupies 2 bytes in memory. It has an extra byte of overhead beyond a regular 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.
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.