- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
自从我开始使用 .NET 以来,这一直是我的烦恼,但我很好奇以防我遗漏了什么。我的代码片段无法编译(请原谅示例的强制性质),因为(根据编译器)缺少返回语句:
public enum Decision { Yes, No}
public class Test
{
public string GetDecision(Decision decision)
{
switch (decision)
{
case Decision.Yes:
return "Yes, that's my decision";
case Decision.No:
return "No, that's my decision";
}
}
}
现在我知道我可以简单地放置一个默认语句来摆脱编译器警告,但在我看来,不仅是冗余代码,而且是危险代码。如果枚举在另一个文件中,并且另一个开发人员出现并将 Maybe 添加到我的枚举中,它将由我的默认子句处理,该子句对 Maybe 一无所知,并且确实存在很有可能我们引入了逻辑错误。
然而,如果编译器让我使用上面的代码,它就可以确定我们遇到了问题,因为我的 case 语句将不再涵盖枚举中的所有值。对我来说当然听起来安全多了。
这对我来说根本就是错误的,我想知道它是否只是我遗漏的东西,或者我们在 switch 语句中使用枚举时是否必须非常小心?
编辑:我知道我可以在默认情况下引发异常或在 switch 之外添加一个返回,但这仍然是从根本上解决不应是错误的编译器错误的技巧。
关于枚举实际上只是一个 int,这是 .NET 的肮脏小 secret 之一,真的很尴尬。请让我声明一个具有有限数量可能性的枚举,并给我一个编译:
Decision fred = (Decision)123;
然后如果有人尝试类似这样的事情就抛出异常:
int foo = 123;
Decision fred = (Decision)foo;
编辑 2:
一些人对当枚举在不同的程序集中会发生什么以及这将如何导致问题发表评论。我的观点是,这是我认为应该发生的行为。如果我更改方法签名,这将导致问题,我的前提是更改枚举应该是相同的。我的印象是很多人认为我不了解 .NET 中的枚举。我只是认为这种行为是错误的,我希望有人可能知道一些非常晦涩的特性,这些特性会改变我对 .NET 枚举的看法。
最佳答案
哎呀,情况比处理枚举要糟糕得多。我们甚至不为 bool 做这个!
public class Test {
public string GetDecision(bool decision) {
switch (decision) {
case true: return "Yes, that's my decision";
case false: return "No, that's my decision";
}
}
}
产生同样的错误。
即使您解决了枚举能够接受任何值的所有问题,您仍然会遇到这个问题。语言的流分析规则根本不会将没有默认值的开关视为所有可能代码路径的“穷举”,即使你我都知道它们是穷举的。
我非常想解决这个问题,但坦率地说,我们有比解决这个愚蠢的小问题更重要的优先事项,所以我们从来没有抽出时间来解决它。
关于c# - 处理枚举时没有默认的switch语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1098644/
我是一名优秀的程序员,十分优秀!