【问题标题】:Branch in C# Based on Boolean Pattern?基于布尔模式的 C# 分支?
【发布时间】:2016-05-14 09:25:05
【问题描述】:

需要基于数组中 16 种不同布尔模式之一在 C# (.NET 4.6.1) 中进行分支(为了在此消息中的可读性,0==false 和 1==true):

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

此时不关心整体性能,对于 16 个案例中的每一个案例,有什么好的方法可以使分支易于阅读?有些中间有“00”的应该表现相同,有些则不然。

一个想法是将每个模式转换为一个字符串,然后执行一个 Switch 或 16 个“if”语句,这不是很好。每个模式都是 BitArray 的重要部分,被提取并转换为 bool 数组。

【问题讨论】:

  • 也许我误解了你的问题,但为什么不将这些位转换为数字(例如byte)并在该数字上执行switch
  • @Wai Ha Lee,如何将 4 个布尔值/位转换为一个字节?
  • 嗯。假设您会得到很多答案,我将其写为临时评论。我很快就会写一个答案。

标签: c# switch-statement pattern-matching bitarray


【解决方案1】:

(一种方法)将您的四个布尔值转换为一个字节:

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

重载使您可以灵活地以两种方式之一进行调用:

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

我无法让二进制文字工作(使用 Visual Studio 2015,针对 .NET 4.6.1)。不过,像 nameof 这样的其他 C# 6.0 功能也可以使用。现在我正在恢复到 5.0 的行为并将二进制文件保留为 cmets。

如果您正在编译为 .NET 4.6.1,我假设您使用的是 C# 6.0 功能,例如 binary literals,这将有助于提高可读性。在这种情况下,您可以对 switch 语句的情况使用如下语法:

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

    // other cases elided

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

请注意,我以 1 (0001) 和 9 (1001) 为例,因为您说:

中间有“00”的一些应该表现相同,而另一些则不然。

如果您不使用 C# 6.0 功能,只需将二进制文字替换为 cmets 中的等效数字。

【讨论】:

  • 我不习惯 C# 6.0(在我工作的时候使用 5.0)所以这 似乎 就像我读到的正确语法。
  • VS2015 抱怨二进制文字的使用。仍在调查中。
  • 嗯 - 我自己只是尝试使用二进制文字 - 肯定 具有其他 C# 6.0 功能,例如 nameof,但二进制文字不起作用。为混乱道歉。我修改了我的答案,不使用二进制文字。
猜你喜欢
  • 1970-01-01
  • 2011-05-08
  • 2019-05-30
  • 2016-03-20
  • 1970-01-01
  • 2013-12-03
  • 1970-01-01
  • 2017-05-23
  • 2015-05-14
相关资源
最近更新 更多