4

此时我有以下代码。

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

我正在考虑添加一个额外的功能,以便我可以foreach所有值基于它返回一个字符串。所以,我会按如下方式进行映射。

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

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

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

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

还是我只是让自己感到困惑,应该立即停止?

4

4 回答 4

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
}
于 2013-01-21T09:14:43.240 回答
1

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

  1. 一种在字典中查找单个枚举并为其返回(可能已本地化)字符串的方法。
  2. 另一种方法将字典中的所有值作为 IEnumerable 返回。

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

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

于 2013-01-21T09:13:10.563 回答
1

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

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

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

...然后根据需要使用反射检索描述。不是闪电般快速,但我经常使用将以 WPF 形式显示的标签来执行此操作,其中少数GetCustomAttributes()调用是我最不关心的性能问题。:)

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

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

于 2013-01-21T09:24:18.283 回答
0

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

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

枚举有几个问题: 

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

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

   

博文 Enumeration classes描述了公共抽象类 Enumeration 以及如何从中创建派生类。

于 2013-04-07T21:46:25.533 回答