自从我开始使用 .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/
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow