我已经开始使用这种格式的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
代码可能会变短
这些优势在我看来并不强大。