Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当请求更多功能时,是否应将枚举重构为类?_C#_Class Structure - Fatal编程技术网

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

C# 当请求更多功能时,是否应将枚举重构为类?,c#,class-structure,C#,Class Structure,在这一点上,我有以下代码 internal enum Genders { Male, Female, NotSure, Other } 我正在考虑添加一个额外的功能,这样我可以foreach所有的值,并基于此返回一个字符串。因此,我将进行如下映射 Male -> "boy" Female -> "girl" NotSure -> "oh-boy" Other -> "cow" 我应该将枚举重构为一个类,还是建议只将ToString值分配给不

在这一点上,我有以下代码

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";
}
private IEnumerable GetGenders()
{
收益回报“男孩”;
收益回报“女孩”;
收益回报“哦男孩”;
产量回报“牛”;
}

或者我只是把自己弄糊涂了,应该立即停止吗?

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

  • 在字典中查找单个枚举并 返回它的(可能是本地化的)字符串
  • 另一个方法,将字典中的所有值作为 我数不清
  • 我认为,如果您想要一个枚举的所有字符串的列表,那么很可能还需要查找一个特定的枚举。如果您需要这两种方法,那么您希望为枚举字符串列表提供一个实现,以确保这两种方法不会失去同步,并且(当然)您不会重复自己的操作


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

    考虑改为向枚举添加扩展名

    例如,您可以这样做:

    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
    }
    
    扩展如下所示:

    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
    }
    

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

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

    internal enum Genders
    {
      [Description("boy")]
      Male,
      [Description("girl")]
      Female,
      [Description("oh-boy")]
      NotSure,
      [Description("cow")]
      Other
    }
    
    …然后根据需要使用反射检索描述。不是闪电般的快,但我经常使用将以WPF形式显示的标签来实现这一点,其中少量调用是我最不关心的性能问题

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


    还可以使用方法枚举枚举的成员。因此,实际上,无论哪种方式,你都可以做你想做的事情,这只是一个让事情复杂化还是简单化对你来说是否值得的问题。

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

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

    枚举有几个问题:

    • 与枚举相关的行为分散在 应用
    • 新的枚举值需要进行鸟枪操作
    • 枚举不遵循开闭原则
    (来自)

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

    对我来说似乎是个人喜好的问题。主要取决于枚举/类的预期复杂性级别。如果只是字符串映射,我个人会将其保留为enum,但这也是个人偏好的问题。我们过去一直在使用这种方法,但我们不得不拒绝它,因为它使字符串本地化变得更加困难。我同意,但问题没有提到本地化。我正在一个全英文的应用程序中使用此方法,并发现它非常适合此用途。:)我在这里使用的一种方法是使用
    Description()
    方法,根据枚举的完全限定类型名及其值(例如
    MyNamespace.MyEnum.Three
    )从相关的特定语言资源文件中查找资源表中的字符串。在没有可用资源的情况下,我们只是将枚举键作为字符串返回。@MatthewWatson幸运的是,本地化不会成为问题。这些字符串实例将用于查询数据库,数据库将始终使用英语。@tomfanning我将这两种方法结合起来,推出了我自己的
    LocalizedDescriptionAttribute
    类(派生自
    DescriptionAttribute
    ),该类同时使用资源键和默认描述字符串,在找不到资源文件时使用。我喜欢这种方法,因为它提供了一个回退字符串值,还因为它是可本地化的,但也与可能希望查找附加的
    DescriptionAttribute
    的系统兼容,这些系统比较常见。速度根本不是问题。我不确定“反思”是什么意思。这是@AmadeusHein建议的代码还是其他意思?我宁愿不要