假设我们有一个接受枚举值的方法.在此方法检查该值是否有效之后,它将switch
覆盖可能的值.所以问题是,在验证了值范围后,处理意外值的首选方法是什么?
例如:
enum Mood { Happy, Sad } public void PrintMood(Mood mood) { if (!Enum.IsDefined(typeof(Mood), mood)) { throw new ArgumentOutOfRangeException("mood"); } switch (mood) { case Happy: Console.WriteLine("I am happy"); break; case Sad: Console.WriteLine("I am sad"); break; default: // what should we do here? }
处理default
案件的首选方法是什么?
发表评论 // can never happen
Debug.Fail()
(或Debug.Assert(false)
)
throw new NotImplementedException()
(或任何其他例外)
其他一些我没有想过的方法
Bill K.. 11
我猜大多数上述答案都是有效的,但我不确定是否正确.
正确的答案是,你很少使用OO语言,它表明你做错了.在这种情况下,它是您的Enum类有问题的完美指示.
您应该只调用Console.WriteLine(mood.moodMessage()),并为每个状态定义moodMessage.
如果添加了新状态 - 所有代码都应自动调整,则不会出现任何故障,抛出异常或需要更改.
编辑:回复评论.
在您的示例中,要成为"Good OO",文件模式的功能将由FileMode对象控制.它可以包含一个具有"open,read,write ..."操作的委托对象,这些操作对于每个FileMode都是不同的,因此File.open("name",FileMode.Create)可以实现为(抱歉不熟悉API):
open(String name, FileMode mode) { // May throw an exception if, for instance, mode is Open and file doesn't exist // May also create the file depending on Mode FileHandle fh = mode.getHandle(name); ... code to actually open fh here... // Let Truncate and append do their special handling mode.setPosition(fh); }
这比使用交换机尝试更简洁......(顺便说一下,这些方法既可以是包私有,也可以委托给"模式"类)
当OO完成时,每个方法看起来都像几行真正可以理解的简单代码 - 太简单了.你总觉得有一些大杂乱的"芝士核"将所有小的nacho物体放在一起,但是你找不到它 - 它一直是玉米片......
我猜大多数上述答案都是有效的,但我不确定是否正确.
正确的答案是,你很少使用OO语言,它表明你做错了.在这种情况下,它是您的Enum类有问题的完美指示.
您应该只调用Console.WriteLine(mood.moodMessage()),并为每个状态定义moodMessage.
如果添加了新状态 - 所有代码都应自动调整,则不会出现任何故障,抛出异常或需要更改.
编辑:回复评论.
在您的示例中,要成为"Good OO",文件模式的功能将由FileMode对象控制.它可以包含一个具有"open,read,write ..."操作的委托对象,这些操作对于每个FileMode都是不同的,因此File.open("name",FileMode.Create)可以实现为(抱歉不熟悉API):
open(String name, FileMode mode) { // May throw an exception if, for instance, mode is Open and file doesn't exist // May also create the file depending on Mode FileHandle fh = mode.getHandle(name); ... code to actually open fh here... // Let Truncate and append do their special handling mode.setPosition(fh); }
这比使用交换机尝试更简洁......(顺便说一下,这些方法既可以是包私有,也可以委托给"模式"类)
当OO完成时,每个方法看起来都像几行真正可以理解的简单代码 - 太简单了.你总觉得有一些大杂乱的"芝士核"将所有小的nacho物体放在一起,但是你找不到它 - 它一直是玉米片......
我更喜欢throw new NotImplementedException("Unhandled Mood: " + mood)
.关键是枚举可能在将来发生变化,并且此方法可能不会相应更新.抛出异常似乎是最安全的方法.
我不喜欢这个Debug.Fail()
方法,因为该方法可能是库的一部分,并且可能无法在调试模式下测试新值.在这种情况下,使用该库的其他应用程序可能会面临奇怪的运行时行为,而在抛出异常的情况下,错误将立即被知道.
注意:NotImplementedException
存在于commons.lang
.
在Java中,标准方法是抛出一个AssertionError
,原因有两个:
这可确保即使asserts
被禁用,也会引发错误.
你断言没有其他的枚举值,所以AssertionError
记录你的假设比NotImplementedException
(Java无论如何).