将枚举转换为字符串的最佳实践方法是什么?

时间:2010-03-31 21:57:54

标签: c# string enums

我有这样的枚举:

public enum ObectTypes
{
    TypeOne,
    TypeTwo,
    TypeThree,
    ...
    TypeTwenty
 }

然后我需要将此枚举转换为字符串。现在我这样做:

public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
    string result = string.Empty;
    switch (typeObj)
    {
        case ObjectTypes.TypeOne: result = "This is type T123"; break;
        case ObjectTypes.TypeTwo: result = "Oh man! This is type T234"; break;
        ...
        case ObjectTypes.TypeTwenty: result = "This is type last"; break;
    }

    return result;
}

我很确定有更好的方法可以做到这一点,我正在寻找一些良好的实践解决方案。

编辑:结果字符串中没有一个模式。

提前致谢。

10 个答案:

答案 0 :(得分:19)

我使用[Description]

中的System.ComponentModel属性

示例:

public enum RoleType
{
    [Description("Allows access to public information")] Guest = 0,
    [Description("Allows access to the blog")] BlogReader = 4,
}

然后从中读取我

public static string ReadDescription<T>(T enumMember)
{
    var type = typeof (T);

    var fi = type.GetField(enumMember.ToString());
    var attributes = (DescriptionAttribute[]) 
            fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
    return attributes.Length > 0 ? 
        attributes[0].Description : 
        enumMember.ToString();
}

然后使用

ReadDescription(RoleType.Guest);

注意:此解决方案假定单个文化应用程序,因为没有专门询问有关多种文化的内容。如果您处于需要处理多种文化的情况,我会使用DescriptionAttribute或类似的方法将密钥存储到文化感知资源文件中。虽然您可以将枚举成员直接存储在.resx文件中,该文件可以创建最紧密的耦合。我认为没有理由要将应用程序的内部工作(枚举成员名称)与为国际化目的而存在的键值相结合。

答案 1 :(得分:9)

如果您需要自定义字符串,最好的选择是制作Dictionary< ObjectTypes, string>,然后进行字典查找。

如果你对默认的ToString()功能没问题,只需使用typeObj.ToString();

对于字典方法,你可以这样做:

private static Dictionary<ObjectTypes, string> enumLookup;

static MyClass()
{
    enumLookup = new Dictionary<ObjectTypes, string>();
    enumLookup.Add(ObjectTypes.TypeOne, "This is type T123");
    enumLookup.Add(ObjectTypes.TypeTwo, "This is type T234");
    // enumLookup.Add...

}

您的方法变为:

public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
     // Shouldn't need TryGetValue, unless you're expecting people to mess  with your enum values...
     return enumLookup[typeObj];
}

答案 2 :(得分:4)

使用建议的资源方式:

string GetName(Enum e) {
     return Properties.Resources.ResourcesManager.GetString("_enum_"+e.GetType().ToString().Replace('.','_'));
}

错误处理更多..

答案 3 :(得分:2)

我认为最简单的方法是使用一个在枚举值和首选短名称之间映射的函数,然后创建另一个生成完整消息的函数。

internal static string MapToName(ObjectTypes value) {
  switch (value) { 
    case ObjectTypes.TypeOne: return "T123";
    case ObjectTypes.TypeTwo: return "T234";
    ...
  }
}

public string ConvertToCustomTypeName(ObjectTypes value) {
  return String.Format("This is type {0}", MapToName(value));
}

答案 4 :(得分:1)

我曾经在枚举字段中使用了一个自定义属性,它接受了一个字符串参数,然后写了一个函数来在给定枚举值时提取字符串。

答案 5 :(得分:1)

如果您只想使用枚举名称(即TypeOne),您只需在枚举本身上调用ToString()

typeObj.ToString()

如果您想要一个基于类型的自定义字符串,您有几个不同的选项。你拥有的switch语句是可以的,但如果你有大量的枚举,保持它会变得混乱。或者您可以使用枚举类型作为键并使用字符串作为值来设置字典。

public enum ObectTypes
{
   One,
   Two
}

Dictionary<ObectTypes, String> myDic = new Dictionary<ObectTypes, string>();
myDic.Add( ObectTypes.One, "Something here for One" );
myDic.Add( ObectTypes.Two, "Something here for Two" );

答案 6 :(得分:1)

我不太相信这个......为什么没有人建议资源文件?

将枚举值映射到编译代码中的字符串是一个很好的快速黑客,但从长远来看这是一个不好的做法,并且很难重构代码。如果从枚举中添加(或减去)值,该怎么办?如果您使用资源文件中的字符串,您只需添加(或删除)一个条目。

答案 7 :(得分:1)

我会将这些值放在数据库中。角色通常属于数据库,原因如下:

  1. 可能需要针对角色运行报告,因此需要显示说明。
  2. 可以在不部署新代码的情况下配置角色定义。
  3. 应使用关键约束强制执行角色。
  4. 如果操作正确,从数据库中获取角色不应该是性能问题。此外,由于角色定义表很少更改,因此它非常适合缓存。

    如果你发现自己不得不乱搞Enum来使其工作,也许你不应该使用枚举。给定正确的位置,一切都应该在代码中流动得更好,几乎没有黑客攻击。授予的Enum有他们的位置;例如,一个相当静态的互斥状态。

答案 8 :(得分:0)

这要求重构,我会说。

Replace Type Code With Class

答案 9 :(得分:0)

你已经使用的并不是一个糟糕的模式。几乎所有其他选项都有自己的问题。如果您在此类型中使用F#,则可以执行以下操作:

type ObjectTypes =
| TypeOne
| TypeTwo
| TypeThree
...
| TypeTwenty
with override this.ToString() =
    match this with
    | TypeOne -> "This is type T123"
    | TypeTwo -> "Oh man! This is type T234"
    ...
    | TypeTwenty -> "This is type last"
    | _ -> "This is any other type that wasn't explicitly specified"

当然,使用F#模式匹配,您可以获得比使用简单C#switch语句更多的控制权。