当前位置:  开发笔记 > 编程语言 > 正文

处理意外枚举值的首选方法是什么?

如何解决《处理意外枚举值的首选方法是什么?》经验,为你挑选了3个好方法。

假设我们有一个接受枚举值的方法.在此方法检查该值是否有效之后,它将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物体放在一起,但是你找不到它 - 它一直是玉米片......



1> Bill K..:

我猜大多数上述答案都是有效的,但我不确定是否正确.

正确的答案是,你很少使用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物体放在一起,但是你找不到它 - 它一直是玉米片......


哇,我没有说任何关于枚举不好的事情!我喜欢类型安全的枚举! - 你指定的用途很棒.这是switch语句有问题.这表明应该将行为移入枚举.
枚举上的开关总是可以通过调用委托函数来替换 - 它们是完全相同构造的转换.关于OO没有任何魔力,它只是让你组织你的代码,以便应该在一起的代码.

2> Hosam Aly..:

我更喜欢throw new NotImplementedException("Unhandled Mood: " + mood).关键是枚举可能在将来发生变化,并且此方法可能不会相应更新.抛出异常似乎是最安全的方法.

我不喜欢这个Debug.Fail()方法,因为该方法可能是库的一部分,并且可能无法在调试模式下测试新值.在这种情况下,使用该库的其他应用程序可能会面临奇怪的运行时行为,而在抛出异常的情况下,错误将立即被知道.

注意:NotImplementedException存在于commons.lang.



3> Michael Myer..:

在Java中,标准方法是抛出一个AssertionError,原因有两个:

    这可确保即使asserts被禁用,也会引发错误.

    你断言没有其他的枚举值,所以AssertionError记录你的假设比NotImplementedException(Java无论如何).

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有