C# 7 开关/机箱使用"when"不打算使用的方式



我已经开始使用这种格式的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(但真正的问题是(误用/滥用(使用case

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

有人建议我发布一个我在评论中放置的示例。这是一个不同的。有一个 if-then 示例,后跟一个案例。它们绝不是相同的,只是为了表明我的意思是嵌套 if 的清晰度。

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??");
        }
    }
}

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

在您的特定示例中,打开hour会更自然。

一系列if语句(带return s(对我来说会更自然地阅读。

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

将其与一直可用的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清楚地表明您要检查某些"主"变量的各种值,这些值可能会被其他变量修改。虽然if-else有相当通用的条件。
  • 如果您有义务在 if-else 代码子句周围加上大括号{},则switch代码可能会变短

这些优势在我看来并不强大。

最新更新