当需要更多的功能时,enum是否应该重构为一个类

本文关键字:重构 一个 是否 功能 enum | 更新日期: 2023-09-27 17:54:57

现在我有了下面的代码:

internal enum Genders
{
  Male,
  Female,
  NotSure,
  Other
}

我正在考虑添加一个额外的功能,这样我就可以foreach所有的值返回一个字符串基于此。因此,我将按照如下方式进行映射。

Male    -> "boy"
Female  -> "girl"
NotSure -> "oh-boy"
Other   -> "cow"
我应该重构enum到一个类中,还是建议只将ToString值赋给不同的enum状态?我在谷歌上搜索过,但没有看到任何代码示例,所以我不确定这样做是否明智。 也许创建一个辅助类并使用这样的方法会更好?
private IEnumerable<String> GetGenders()
{
  yield return "boy";
  yield return "girl";
  yield return "oh-boy";
  yield return "cow";
}
或者我只是把自己弄糊涂了,应该立即停止?

当需要更多的功能时,enum是否应该重构为一个类

考虑给Enum添加一个扩展。

例如,你可以这样做:

Gender.Male.Description (which would return string "boy")

扩展名看起来像这样:

    /// <summary>
    /// Defines an EnumExtensions type.
    /// </summary>
    public static class EnumExtensions
    {
        /// <summary>
        /// Gets the value from a DescriptionAttribute applied to the enum.
        /// </summary>
        /// <param name="value">Enum value.</param>
        /// <returns>DescriptionAttribute value, or null if no attribute is applied.</returns>
        public static string Description(this Enum value)
        {
            var type = value.GetType();
            var fieldInfo = type.GetField(value.ToString(CultureInfo.InvariantCulture));
            var descriptionAttributes = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            return descriptionAttributes.Length > 0
                       ? ((DescriptionAttribute)descriptionAttributes[0]).Description
                       : null;
        }

你的enum看起来像这样:

public enum Gender
{
    [Description("boy")]
    Male,
    [Description("girl")]
    Female,
    [Description("oh-boy")]
    NotSure,
    [Description("cow")]
    Other
}

添加这样的功能是合理的,但不一定以您建议的方式。我将使用字典将枚举值映射到它们的翻译,并添加两个方法:

  1. 在字典和中查找单个枚举的方法返回它的(可能是本地化的)字符串。
  2. 另一个方法,它返回字典中所有的值IEnumerable。

我认为这是极有可能的,如果你想要一个枚举的所有字符串的列表,你也会想要查找一个特定的枚举。如果你需要这两种方法,你希望对枚举字符串列表有一个单一的实现,以确保这两个方法不会不同步,并且(当然)你不会重复自己。

(我们必须将任何可以显示给用户的枚举映射到字符串,因为我们不能使用内置的枚举. tostring(),因为它是"程序员语言",而且没有本地化。)

嗯,这取决于你的个人喜好和应用程序的要求。枚举的一大优点是定义了一组有限的数值,即使是编译器和开发环境也能识别这些数值,而用字符串集合代替它们则会否定这一点。如果您希望在某个时候将枚举值存储在数据库字段中,这可能也很重要。

如果性能不是一个大问题,你可以用DescriptionAttributes装饰你的enum,将它们与字符串名称或任何你想要的元数据相关联:

internal enum Genders
{
  [Description("boy")]
  Male,
  [Description("girl")]
  Female,
  [Description("oh-boy")]
  NotSure,
  [Description("cow")]
  Other
}

…然后根据需要使用反射检索描述。虽然速度不是很快,但我经常使用以WPF形式显示的标签,其中少数GetCustomAttributes()调用是我最不关心的性能问题。:)

如果您想更花哨一点,这种方法的一个优点(与硬编码字符串相反)是您可以将您的描述绑定到应用程序资源中包含的字符串(因此,例如,您可以为不同的语言提供本地化版本)。我相信微软在他们的一些库中采用了这种方法(或者我在想别的什么?)当然,你可以通过调用枚举值上的ToString()来检索在代码中定义的枚举成员的名称。

您也可以用Enum.GetValues()方法枚举枚举枚举的成员。所以,你可以用任何一种方式来做你想做的事情,只是一个问题,是值得你把事情复杂化还是保持简单。

这取决于您需要实现的复杂程度。如果只是英语中的描述,你可以按照其他答案中的建议使用DescriptionAttributes。如果你需要支持多种语言,你必须使用本地化资源(在.resx文件中或在数据库中)-例如,参见http://www.codeproject.com/Articles/19953/Localizing-NET-Enums

但是对于更复杂的场景,使用enum是不够的。

枚举有几个问题:

    与枚举相关的行为分散在应用
  • 新的枚举值需要霰弹枪手术
  • 枚举不遵循开闭原则

(http://lostechies.com/jimmybogard/2008/08/12/enumeration-classes/)

博客文章描述的枚举类public抽象类Enumeration,以及如何从它创建派生类