【问题标题】:C# Enum return string with breaksC# 枚举返回带中断的字符串
【发布时间】:2011-08-06 06:39:07
【问题描述】:

我需要我的枚举来返回一个特定的字符串,但我不知道如何让它返回一个带有中断的字符串,而没有进行转换的方法。是否可以在没有辅助方法的情况下使LicenseTypes.DISCOUNT_EARLY_ADOPTER 返回DISCOUNT EARLY-ADOPTER

// All license types
public enum LicenseTypes
{
    DISCOUNT,
    DISCOUNT_EARLY_ADOPTER,
    COMMERCIAL,
    COMMERCIAL_EARLY_ADOPTER
}

// Convert enum to correct string
public static string LicenseTypeToString(LicenseTypes Enum)
{
    if (Enum == LicenseTypes.COMMERCIAL)
        return "COMMERCIAL";
    else if (Enum == LicenseTypes.COMMERCIAL_EARLY_ADOPTER)
        return "COMMERCIAL EARLY-ADOPTER";
    else if (Enum == LicenseTypes.DISCOUNT)
        return "DISCOUNT";
    else if (Enum == LicenseTypes.DISCOUNT_EARLY_ADOPTER)
        return "DISCOUNT EARLY-ADOPTER";
    else
        return "ERROR";
}

【问题讨论】:

  • 带断点的字符串是什么意思?
  • @Bolt,我的意思是它返回字符串“DISCOUNT EARLY-ADOPTER”,其中有空格,枚举不喜欢空格,所以我必须强调它们
  • 你见过post 讨论使用 System.ComponentModel.DescriptionAttribute 来创建更好的带空格的枚举描述吗?
  • 尽管您可能讨厌它,但实际上我认为您的简单辅助方法方法并没有什么特别的问题。我只建议使用switch 语句而不是一堆if/else 块,因为编译器可以更好地优化它。

标签: c# asp.net enums


【解决方案1】:

首先,辅助方法的一个单独选项就是拥有一个您填充一次的Dictionary<LicenseTypes, string>。老实说,这可能是最简单的方法:

private static readonly Dictionary<LicenseTypes, string> LicenseDesciptions =
    new Dictionary<LicenseTypes, string> 
{
    { LicenseTypes.COMMERCIAL, "COMMERCIAL" },
    { LicenseTypes.COMMERCIAL_EARLY_ADOPTER, "COMMERCIAL EARLY-ADOPTER" },
    { LicenseTypes.DOMESTIC, "DOMESTIC" },
    { LicenseTypes.DOMESTIC_EARLY_ADOPTER, "DOMESTIC EARLY-ADOPTER" },
};

(如 cmets 中所述,另一种选择是 switch/case ......但我个人更喜欢这种方式,因为实际上你有一个 data 映射,所以使用data 结构而不是 执行流程 结构。这也意味着您可以根据需要将字典换成不同的语言等。)

其次,一种选择是使用[Description] 属性(或您自己的属性,如果您愿意)来装饰每个枚举值,并通过反射找出这一点 - Unconstrained Melody 有一个扩展方法可以很容易地做到这一点:

// Throws ArgumentOutOfRangeException if the licenseType value isn't defined
// or doesn't have a description.
string description = licenseType.GetDescription();

此外,它应该遵循 .NET 命名约定:

public enum LicenseType // Singular as it's not a Flags enum
{
    Discount,
    DiscountEarlyAdopter,
    Commercial,
    CommercialEarlyAdopter
}

【讨论】:

  • 谢谢乔恩!很好的答案,前一周我也买了你的书,我要开始学习了,看起来很棒!
  • +1:我喜欢你关于使用数据结构进行数据映射的论点。
  • @Tom:酷——希望你喜欢这本书。如果有什么不明白的,请联系我 :)
【解决方案2】:

一点反射和属性魔法,这应该只是回答它:)
Getting attributes of Enum's value

也可以设为extension method

这是它的外观(还添加了泛型):

public static class MyExtensionsClass
{
    public static string ToDescriptionString<T>(this T val)
        where T : struct, IConvertible
    {
        if (typeof(T).IsEnum) 
        {
           var type = val.GetType();
           var memInfo = type.GetMember(val.ToString());
           var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
           return ((DescriptionAttribute)attributes[0]).Description;
        }
        return ""; //all paths must return a value
    }
}

public enum LicenseTypes
{
    [Description("DISCOUNT")]
    DISCOUNT,
    [Description("DISCOUNT EARLY-ADOPTER")]
    DISCOUNT_EARLY_ADOPTER,
    [Description("COMMERCIAL")]
    COMMERCIAL,
    [Description("COMMERCIAL EARLY-ADOPTER")]
    COMMERCIAL_EARLY_ADOPTER
}

谢谢写这些的人:

祝你好运!

【讨论】:

    【解决方案3】:

    虽然它不会消除辅助方法,但请注意,在您的情况下,您可以只对使用 ToString 无法获得的值进行特殊处理:

    switch (Enum) {
        case LicenseTypes.COMMERCIAL_EARLY_ADOPTER:
            return "COMMERCIAL EARLY-ADOPTER";
        case LicenseTypes.DISCOUNT_EARLY_ADOPTER:
            return "DISCOUNT EARLY-ADOPTER";
        default
            return Enum.ToString();
    }
    

    【讨论】:

      【解决方案4】:

      我从 Google 的 dotnet 客户端使用它 - StringValueAttribute.csUtilities.cs

      public enum LicenseType
      {
           [StringValue("DISCOUNT")] Discount,
           [StringValue("DISCOUNT EARLY-ADOPTER")] DiscountEarlyAdopter,
           [StringValue("COMMERCIAL")] Commercial,
           [StringValue("COMMERCIAL EARLY-ADOPTER")] CommercialEarlyAdopter
      }
      

      那么你可以简单地这样做:

      licenseType.GetStringValue();
      

      【讨论】:

        【解决方案5】:

        使用“G”格式转换为字符串,然后将“_”(下划线)替换为空格:

        LicensceTypes license = LicenseTypes.COMMERCIAL_EARLY_ADOPTERS;
        string licenseDescription = license.ToString("G").Replace('_', ' ');
        // licenseDescription = "COMMERCIAL EARLY ADOPTERS"
        

        【讨论】:

        • 感谢您的回答,但如果我们将来添加其他带有下划线等的许可证,这将很难维护!
        • 不过,这会忽略 OP 所需的连字符 (-)。
        【解决方案6】:

        我想我会使用一个类来避免这种情况。 :/

        public class LicenceType
        {
            private string name;
            public LicenceType(string Name)
            {
                this.name = Name;
            }
            public override string ToString()
            {
                return name;
            }
        }
        
        public static class LicenceTypes
        {
            public static LicenceType DISCOUNT = new LicenceType("DISCOUNT");
            public static LicenceType DISCOUNT_EARLY_ADOPTER= new LicenceType("DISCOUNT EARLY-ADOPTER");
            public static LicenceType COMMERCIAL= new LicenceType("COMMERCIAL");
            public static LicenceType COMMERCIAL_EARLY_ADOPTER= new LicenceType("COMMERCIAL EARLY-ADOPTER");
        }
        

        【讨论】:

          猜你喜欢
          • 2018-11-24
          • 2022-01-12
          • 1970-01-01
          • 2022-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-18
          相关资源
          最近更新 更多