9

考虑以下代码:

        private enum myEnum
        {
            A,
            B
        }
        private void myMethod(myEnum m)
        {
            switch (m)
            {
                case myEnum.A:
                    //do stuff
                break;
                case myEnum.B:
                   //do stuff
                break;
                default:
                   throw new NotImplementedException(m.ToString());
            }
        }

如果我将第三个成员 C 添加到 myEnum,我只会在运行时收到 NotImplementedException 警告

我想做的是让编译器在有未处理案例没有默认值的开关时警告我:案例。

有没有办法做到这一点,或者这个问题的其他解决方案,最终目标是在编译时被警告缺少某些东西?

4

5 回答 5

6

不幸的是,这里没有编译器功能可以为您执行此操作。

与其拥有枚举,不如拥有一个基类或接口。MyMethod 是在接口上定义的。

现在,每个枚举成员都成为具有不同行为的 myMethod 类。如果您添加一个类(以扩展选项,目前您将添加一个枚举项)但不实现 myMethod,您将收到编译器错误。

在代码中有很多地方,您在选择语句中提供不同的行为是您可能需要使用多态性的味道。

编辑

我能给出的最好建议是为依赖 switch 语句的每个函数构建单元测试,并为枚举中的每个值调用它(您可以在运行时使用 Enum 类的 GetValues 成员获取值)

于 2009-04-02T08:38:19.190 回答
2

不,语言中没有任何内容可以检查这一点。

你可以有一个:

default:
    throw new ArgumentOutOfRangeException("Invalid value or bug");

情况,但显然这是执行时间而不是编译时间。

于 2009-04-02T08:53:50.260 回答
1

从未使用过它,但FxCop可能会有所帮助。它支持编写自定义规则。当然,这不是编译时检查,而是可以集成到您的流程中的东西。

于 2009-04-02T11:05:35.810 回答
0

这可能成为维护的噩梦,不得不花费大量时间尝试调试 switch 语句中缺少的枚举值。

写了一个小类,使 switch 语句变得更易于维护,

在此处输入图像描述

该类确保所有枚举值都被处理或显式忽略,否则它会抛出 NotImplementedExpcetion。

在此处查看源代码和更多详细信息

于 2013-04-30T22:49:30.140 回答
0

我编写了一个库,用于在 C# 中进行区分联合,这将是在编译时提供详尽匹配的解决方案。见https://github.com/mcintyre321/OneOf

Install-Package OneOf

它具有用于执行 DU 的通用类型,例如 OneOf 一直到 OneOf。其中每一个都有一个 .Match 和一个 .Switch 语句,您可以将它们用于编译器安全类型的行为,例如:

OneOf<A, B> aOrB = GetValue(); 
aOrB .Switch(
    a=> DoSomething(a),
    b=> DoSomethingElse(b)
)
于 2018-11-09T11:05:14.127 回答