如何使用InvalidEnumArgumentException维护代码?

Mar*_*lon 7 c# maintainability

我很好奇你抛出一个代码后如何维护你的代码System.ComponentModel.InvalidEnumArgumentException.

基本上我有一个这样的开关语句:

switch (enumValue)
{
    case MyEnum.Value1:
        break;

    case MyEnum.Value2:
        break;

    default:
        throw new InvalidEnumArgumentException();
}
Run Code Online (Sandbox Code Playgroud)

如果我决定什么更值添加到MyEnum在未来,例如,Value3Value4?这意味着我最终会抛出一个误导性的例外.我该如何防止这种情况?

投掷前我应该使用反射吗?在这种情况下我应该抛出什么异常?我正在寻找建议.


我刚刚在几分钟前发现了这个例外,所以也许我在错误的背景下看这个.如果不支持某个枚举参数(在这种情况下Value3并且Value4不支持),是否抛出此异常?

Joã*_*elo 8

您声明的问题取决于上下文,如果方法接收枚举作为参数,则必须指定它支持的值以及它对未知枚举值的作用.

如果添加更多枚举选项,即使未在默认情况下抛出异常,也需要确定要执行的操作.

请注意,异常特别有用,因为您可以将任何整数作为枚举值传递.

例如:

enum Foo { A, B }

static int Bar(Foo f)
{
    switch (f)
    {
        case Foo.A:
            return 1;
        case Foo.B:
            return 2;
        default:
            throw new InvalidEnumArgumentException("f", (int)f, typeof(Foo));
    }
}

static void Main()
{
    Bar(Foo.A);
    Bar((Foo)99);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你只针对dot net 4.6或更高版本,那么这个例子稍微改进就是用`nameof(f)`替换``f"`字符串. (2认同)

jac*_*rld 5

如果我决定将来向 MyEnum 添加更多值,例如 Value3 和 Value4,该怎么办?这意味着我最终会抛出一个误导性的异常。我将如何防止这种情况?

当您使用时InvalidEnumArgumentException,要理解的关键是argument。通过抛出异常,您是说该方法的参数无效。(InvalidEnumArgumentException源自ArgumentException。)这并不一定意味着该值不是 的成员enum。所以我不会认为它具有误导性。


Doc*_*ick 0

我不会使用您在该上下文中使用的异常。由于 enumValue 是 MyEnum 类型(我猜?),它永远不会包含无效的枚举值。如果您有基于枚举值的开关,如果它们无法识别该值,则需要失败,那么您需要抛出适当的异常(也许只是一个普通的 ArgumentException?),但在大多数情况下,我猜您会让代码运行对未知的枚举值不执行任何操作。

  • 这是不正确的。根据[设计指南的这一补充](http://blogs.msdn.com/b/kcwalina/archive/2004/05/18/134208.aspx),“将任何整数值转换为枚举是合法的即使该值未在枚举中定义。”。 (2认同)