当请求更多功能时,是否应该将枚举重构为类?

时间:2013-01-21 09:07:53

标签: c# class-structure

此时我有以下代码。

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

我正在考虑添加额外的功能,以便我可以 foreach 所有值根据它返回 String 。所以,我会按照以下方式进行映射。

Male    -> "boy"
Female  -> "girl"
NotSure -> "oh-boy"
Other   -> "cow"

我应该将 enum 重构为一个类,还是建议只将 ToString 值分配给不同的枚举状态?我用谷歌搜索了它,但没有看到任何代码示例,所以我不确定这样做是否明智。

也许最好创建一个辅助类并使用这样的方法?

private IEnumerable<String> GetGenders()
{
  yield return "boy";
  yield return "girl";
  yield return "oh-boy";
  yield return "cow";
}

或者我只是困惑自己,应该立即停止?

4 个答案:

答案 0 :(得分:5)

考虑为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;
        }

你的枚举会是这样的:

public enum Gender
{
    [Description("boy")]
    Male,

    [Description("girl")]
    Female,

    [Description("oh-boy")]
    NotSure,

    [Description("cow")]
    Other
}

答案 1 :(得分:1)

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

  1. 在字典中查找单个枚举的方法 返回它的(可能是本地化的)字符串。
  2. 另一种将字典中的所有值作为返回值返回的方法     IEnumerable的。
  3. 我认为如果你想要一个枚举的所有字符串列表,你很可能也想查找一个特定的枚举。如果你需要这两种方法,你希望对枚举字符串列表有一个单独的实现,以确保这两种方法不会失去同步,并且(当然)你不要重复自己。

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

答案 2 :(得分:1)

嗯,这取决于您的个人偏好和应用程序的要求。枚举的一个很大的优点是定义了一组有限的数值,即使编译器和开发环境都知道这些数值,并用一组字符串替换它们会使其无效。如果要在某个时刻将枚举值存储在数据库字段中,这可能也很重要。

如果性能不是一个大问题,您可以使用DescriptionAttributes修饰枚举,将它们与字符串名称或您想要的任何其他元数据相关联:

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

...然后根据需要使用反射检索描述。不是闪电般快,但我会经常使用将以WPF形式显示的标签,其中少数GetCustomAttributes()次呼叫是我性能问题中最少的。 :)

如果你想获得幻想,这种方法的一个优点(与硬编码字符串相反)是你可以将你的描述绑定到应用程序资源中包含的字符串(例如,你可以使用本地化版本不同的语言)。我相信微软会为他们的一些图书馆采用这种方法(或者我在考虑别的什么?)。当然,只需在枚举值上调用ToString(),就可以检索代码中定义的枚举成员的名称。

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

答案 3 :(得分:0)

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

然而,对于使用枚举的更复杂的场景是不够的。

  

枚举存在一些问题:

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

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

博文 Enumeration classes描述了 public abstract class Enumeration以及如何从中创建派生类。