C#7开关/箱使用"当"它不应该被使用的方式

时间:2017-05-21 12:01:58

标签: switch-statement c#-7.0

我开始使用这种switch语句格式。它有效,但有一种纯粹主义观点认为以下是不好的做法吗?从好的方面来说,它比深层嵌套的if语句更具可读性。在不利方面,我不认为它应该像这样使用:

int hour = DateTime.Now.Hour;
string timeWord;

switch ("ignore")
{
    case string x when hour < 12:
        timeWord = "morning";
        break;

    case string x when hour < 18:
        timeWord = "afternoon";
        break;

    case string x when hour < 24:
        timeWord = "evening";
        break;

    default:
        throw new LogicException("Another fine mess you got us into");
}

Console.WriteLine("Good {timeWord}");

default而言,我更喜欢防御性编程。我不喜欢使用默认值作为全能。不可思议的事情发生在惊人的规律性。 (参考:HHGTTG)真正的问题是{mis}使用case

编辑更新 +进一步更新,因为我搞砸了剪切和粘贴

有人建议我发一个我发表评论的例子。这是一个不同的。有一个if-then示例后跟一个案例。它们并不意味着相同,只是为了表明我对嵌套ifs的清晰度的意义。

public class example
{
    static Random rnd = new Random();
    bool B1, B2, B3, B4, B5;
    static bool GetBool() { return rnd.Next(1) == 0 ? false : true; }
    bool Accept() { return GetBool(); }
    bool Decline() { return GetBool(); }
    List<bool?> nullBools = new List<bool?> { false, true, null };
    bool? Other() { return nullBools[rnd.Next(2)]; }
    void MaybeException() { }
    public example()
    {
        // I don't think it is difficult to miss the holes in this logic
        B1 = GetBool(); B2 = GetBool(); B3 = GetBool(); B4 = GetBool();
        if (B1 && B2)
        {
            if (B3)
                if (B4 & B5)
                    if (!Accept() & !Decline())
                        Other();
                    else
                        Decline();
                else
                if (B4 & !B5)
                    if (B1)
                        Decline();
                    else
                        Accept();
                else
                    MaybeException();
        }
        else
        {
            if (!B1 && B2)
                if (B5 & B4)
                    if (!Accept() && Other() != null)
                        Decline();
                    else
                    {
                        if (!Other() == null)
                            if (!Accept())
                                Decline();
                            else
                                Decline();
                    }
                else
                {
                    if (B4 && !B5)
                        Accept();
                    else
                            if (Other() == null)
                        if (!Accept())
                            Decline();
                    Decline();
                }
        }
        // As opposed to

        switch ("IGNORE")
        {
            case string B_0234 when !B1 && !B2 && B3 && B4:
            case string B_1200 when B1 && B2 && !B3 && !B4:
            case string B_1204 when B1 && B2 && !B3 && B4:
            case string B_1234 when B1 && B2 && B3 && B4:
                if (Other() == null)
                    Accept();
                break;

            case string B_0004 when !B1 && !B2 && !B3 && B4:
            case string B_0134 when B1 && !B2 && B3 && B4:
            case string B_1000 when B1 && !B2 && !B3 && !B4:
            case string B_1030 when B1 && !B2 && B3 && !B4:
            case string B_1203 when B1 && B2 && B3 && !B4:
            case string B_1004 when B1 && !B2 && !B3 && B4:  // Compile error duplicate
                if (Other() == null)
                    if (!Accept())
                        Decline();

            case string B_0230 when !B1 && B2 && B3 && !B4:
            case string B_1201 when B1 && B2 && !B3 && B4:
            case string B_1230 when B1 && B2 && B3 && !B4:
                MaybeException();
                break;

            //case string B_0101 when !B1 && B2 && !B3 && B4:
            //case string B_0000 when !B1 && !B2 && !B3 && !B4:

            default:
                throw new Exception("Whoops missed the two above impossible??");
        }
    }
}

2 个答案:

答案 0 :(得分:3)

将它与if-else结构进行比较,该结构一直可用:

if (hour < 12)
{
    timeWord = "morning";
}
else if (hour < 18)
{
    timeWord = "afternoon";
}
else if (hour < 24)
{
    timeWord = "evening";
}
else
{
    throw new LogicException("Another fine mess you got us into");
}

后一个代码具有几乎相同的结构,允许扩展条件,并支持最后的全部else部分。

它没有"ignore"部分,最初可能会引起混淆:

  

这里究竟被忽略了什么?

     

...哦,它是字符串"ignore"本身!

那么case代码结构的优点是什么?我能想到这些:

  • case清楚地表明您要查看某些&#34; main&#34;的各种值。变量,可以由其他变量修改。虽然if-else具有非常通用的条件。
  • 如果您有义务在if-else代码子句中添加大括号{}switch代码可能会缩短

这些优点对我来说并不强烈。

答案 1 :(得分:2)

我个人不会使用这样的结构 - 这是令人困惑的,特别是考虑到你应该接通的对象不参与切换。

在您的特定示例中,启用hour会更加自然。

一系列if语句(带return s)会更自然地向我阅读。

或者,使用返回字符串映射hour的字典可以很好地工作。