2

Need to branch in C# (.NET 4.6.1) based on one of 16 different boolean patterns in an array (for readability in this message, 0==false and 1==true):

   0000
   0010
   0100
   0110
   0001
   0011
   0101
   0111
   1000
   1010
   1100
   1110
   1001
   1011
   1101
   1111

Not being concerned with overall performance at this time, what is a good way to make the branching human-readable for each of the 16 cases? Some of those that have "00" in the middle should behave the same, others not.

One idea is to convert each pattern to a String and then do a Switch or 16 "if" statements, not great. Each pattern is the significant portion of a BitArray, extracted and cast into a bool array.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Snowy
  • 5,942
  • 19
  • 65
  • 119

1 Answers1

4

(One way) to convert your four bools to a byte:

public byte BoolsToByte(IEnumerable<bool> bools)
{
    byte result = 0;
    foreach ( bool value in bools )
    {
        result *= 2;

        if ( value )
            result += 1;
    }

    return result;
}

public byte BoolsToByte(params bool[] bools)
{
    return BoolsToByte(bools.AsEnumerable());
}

where the overload gives you flexibility to call in one of two ways:

  • byte converted = BoolsToByte(bytes);
  • byte converted = BoolsToByte(a, b, c, d);

I haven't been able to get binary literals to work (using Visual Studio 2015, targeting .NET 4.6.1). Other C# 6.0 features like nameof work, though. For now I'm reverting to 5.0 behaviour and leaving binary in as comments.

If you're compiling to .NET 4.6.1, I assume you're using C# 6.0 features such as binary literals which will help with readability. In that case, you can use a syntax for the cases of your switch statement like this:

switch ( converted )
{
    case 0: // 0000
        // elided
        break;
    case 1: // 0001
    case 9: // 1001
        // elided
        break;

    // other cases elided

    case 15: // 1111
        // elided
        break;
}

Note I've combined 1 (0001) and 9 (1001) as an example because you said:

Some of those that have "00" in the middle should behave the same, others not.

If you're not using C# 6.0 features, just replace the binary literals with the numeric equivalents from the comments.

Community
  • 1
  • 1
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
  • I'm not accustomed to C# 6.0 (using 5.0 at the moment where I work) so this *seems* like the right syntax from what I read. – Wai Ha Lee Feb 06 '16 at 19:03
  • VS2015 is complaining about the binary literal usage. Still investigating. – Snowy Feb 08 '16 at 04:33
  • 1
    Hmm - I just tried using binary literals myself - **definitely** had other C# 6.0 features such as `nameof`, but binary literals didn't work. Apologies for the confusion. I've modified my answer to not use binary literals. – Wai Ha Lee Feb 08 '16 at 07:42