拥有许多枚举值(许多>=1000),会带来什么危害?

5

我有一个很长的错误消息列表,根据输入内容,我的业务代码可能会返回其中之一。该列表可能会超过一千个。

我想把它们全部枚举出来,并使用[Description("")]属性记录友好的消息。

类似于:

public enum ErrorMessage
{
     [Description("A first name is required for users.")]
     User_FirstName_Required = 1,
     [Description("The first name is too long.  It cannot exceed 32 characters.")]
     User_FirstName_Length = 2,
     ...
}

我知道枚举是基本类型,具体来说是整数。这么多整数应该不会有任何问题,对吧?
我是否考虑得不够全面?看起来这样应该没问题,但在这样做之前,我想问问社区的意见。
当枚举类型拥有大量值时,.Net是否会以不同的方式处理它们?
更新:
我不想使用资源文件的原因是:
a)我需要能够使用整数值引用每个独特的错误消息。业务层服务于API,还有其他一些东西,必须返回一个整数值列表,表示错误。我不认为资源允许您使用整数访问资源值。我错了吗?
b)没有本地化要求。

汇编元数据往往限制每个分组的不同元素数量为65535。 - Hans Passant
5个回答

6
我认为一个枚举类型有1000个以上的值需要更多的思考。听起来像是需要发明“上帝枚举”反模式来解决这个问题。

我考虑过使用通用的 ErrorMessage 类型来对模型进行处理,但似乎这样做的唯一目的就是减少垂直代码并增加水平代码。我的计划是随着未来需求变得更加明确而迭代出更好的解决方案。 - sohtimsso1970
虽然在一般情况下,我会说这是设计不良的标志,但我认为他是唯一合法的情况——必须作为整数传递的结果代码。 - Loren Pechtel

4
我要指出的主要缺点是将友好描述放在属性中会导致挑战,如果您需要将应用本地化到另一种语言。如果考虑到这一点,最好将字符串放入资源文件中。
枚举本身不应该成为问题,但是将所有错误代码放在一个主列表中可能会令人困惑。您可以考虑为返回代码的不同类别创建单独的枚举,这将使开发人员更容易理解特定功能的可能返回值。如果重要的是代码唯一,请通过明确指定数值来赋予它们不同的数值。

顺便提一下,.NET BCL并没有广泛使用返回代码,并且在现代.NET开发中有些不鼓励使用。它们会带来可维护性问题(你几乎不能删除旧的返回代码或者冒着破坏向后兼容性的风险),并且需要特殊的验证逻辑来处理每个调用的返回值。带状态的验证可以通过IDataErrorInfo实现,其中您使用一个中间类来表示无效状态,但仅允许提交经过验证的更改。这使您可以自由地操作对象,但也可以向用户提供其状态的有效性反馈。与错误代码的等效逻辑通常需要为每个使用编写一个switch语句。


是的,我考虑过本地化,但这并非必需,而且极不可能发生。我想,如果那个要求出现了,我会让团队迭代到其他解决方案。 - sohtimsso1970
你提出了有关在接口中使用有效/无效状态的好观点,但我不同意使用返回类型是被反对的。这个ErrorMessage枚举不是唯一被返回的东西。它是Result<Model>模式的一部分,允许业务层返回许多其他方法无法实现的信息(至少我不能理解)。请记住,这个业务层正在展示各种控制器类型,包括REST和SOAP API。 - sohtimsso1970
@sohtimsso1970,听起来你的用例是一个例外,因为你需要打包更多的信息而不仅仅是返回代码。我更多地是指旧式方法调用每个都返回一个整数的方法,使用一些主要的常量来解释每个方法的结果。在你的情况下,你需要支持多个服务前端,所以一个错误代码来传递验证可能是最好的选择。即使如此,将代码/结果分开将会很有帮助;我认为拥有一个中央的“Result<Model>”将会在以后引起头痛。 - Dan Bryant

2

1000不算很多,你只需要确保底层整数类型足够大(不要在枚举中使用char)。

想想一下,如果你手动输入1000个枚举值,那就太多了,但是如果它们是从某个数据集生成的,这样做可能还有意义。


1

我完全同意duffymo的观点。一个有1000多个值的枚举在设计上看起来很糟糕。更不用说对于开发人员来说,在这样一个“神枚举”上使用智能会相当麻烦:-) 我宁愿使用资源。


我不想使用资源的原因是因为我需要为每个错误返回一个唯一的整数值。业务代码被用于不同的地方,包括一个API,所以有时候我无法传递资源名称,而需要传递一个整数。我会编辑问题以包含这一点。 - sohtimsso1970
顺便问一下,你在运行时读取了 [Description("A first name is required for users.")] 吗?这可能会影响性能。 - user407665
是的,有一个点使用反射来获取描述,但这只会在每个应用程序实例中发生一次,对吧?一旦完成了这个操作,除非应用程序重置,否则不应再次发生。 - sohtimsso1970
回到您关心的能否返回唯一整数值的问题......请再次考虑您的要求。如果您使用资源,处理本地化问题将会更加容易。行业标准做法是使用资源来处理错误代码。有许多工具可以帮助您完成这项工作。 - user407665
确保您的代码在使用资源时跨版本保持一致的一种方法是编写测试,比较不同版本之间的资源文件。 - user407665

0

我认为这很糟糕,对于错误处理,你可以简单地使用资源,就像我看到的那样,你想要做反射并获取描述,这也很糟糕。如果你不想使用资源,你可以为每个业务规则定义不同的枚举,此外,你的不同业务不需要其他错误消息(也不应该这样)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接