将枚举转换为字符串

时间:2009-01-27 15:15:40

标签: .net enums

在.NET 3.5中将Enum转换为String的首选方法是什么?

  • Enum.GetName
  • Enum.Format
  • 的toString

为什么我更喜欢其中一种呢?一个人表现得更好吗?

14 个答案:

答案 0 :(得分:93)

从C#6开始,获取枚举名称的最佳方法是使用新的nameof运算符:

nameof(MyEnum.EnumValue);

// Ouputs
> "EnumValue"

这在编译时有效,枚举被编译结果中的字符串替换,这反过来意味着这是最快的方法。

如果你认为枚举名称的混淆是值得的或重要的,那么使用枚举名称会干扰代码混淆 - 这可能是另一个问题。

答案 1 :(得分:91)

为我们的项目工作......

public static String convertToString(this Enum eff)
{
    return Enum.GetName(eff.GetType(), eff);
}

public static EnumType converToEnum<EnumType>(this String enumValue)  
{
    return (EnumType) Enum.Parse(typeof(EnumType), enumValue);
}

答案 2 :(得分:22)

在我的测试中,Enum.GetName速度更快,而且余量不错。内部ToString来电Enum.GetName。 {4.0} for .NET 4.0,基本要点:

public override String ToString()
{
     return Enum.InternalFormat((RuntimeType)GetType(), GetValue());
}

private static String InternalFormat(RuntimeType eT, Object value)
{
    if (!eT.IsDefined(typeof(System.FlagsAttribute), false))
    {
        String retval = GetName(eT, value); //<== the one
        if (retval == null)
            return value.ToString();
        else
            return retval;
    }
    else
    {
        return InternalFlagsFormat(eT, value);
    }
}

我不能说这是肯定的原因,但测试状态比另一个更快。这两个调用都涉及装箱(实际上它们是反射调用,你实际上是在检索字段名称),并且可能对你的喜好很慢。

  

测试设置:包含8个值的枚举,否。 of iterations = 1000000

     

结果:Enum.GetName =&gt; 700毫秒,ToString =&gt; 2000毫秒

如果速度不明显,我不会关心并使用ToString因为它提供了更清洁的呼叫。对比度

Enum.GetName(typeof(Bla), value)

value.ToString()

答案 3 :(得分:21)

所有这些内部最终都会调用名为InternalGetValueAsString的方法。 ToStringGetName之间的区别在于GetName必须首先验证一些事项:

  1. 您输入的类型不为空。
  2. 您输入的类型实际上是枚举。
  3. 您传入的值不为空。
  4. 您传入的值是枚举实际可以使用的类型,因为它是基础类型或枚举本身的类型。它使用值GetType来检查它。
  5. .ToString不必担心上述任何问题,因为它是在类本身的实例上调用的,而不是在传入的版本中调用,因此,由于{ {1}}方法与静态方法没有相同的验证问题,我会得出结论.ToString是将值作为字符串获取的最快方法。

答案 4 :(得分:16)

我能找到的最好的是this unrelated question on MSDN,其中包含一个回答此问题的XML代码段。这些方法中的任何一个都有相同的缺陷:它们调用enum.toString(),使用Dotfuscation时无法正常工作。其他问题似乎与间接装箱(GetName和Format)有关。不幸的是,我找不到使用上述任何一个的性能原因。

来自xml snippet

的释义
  

将boxed枚举传递给string.Format()或任何其他函数可能导致enum.ToString()被调用。   这会在Dotfuscating时引起问题。您不应使用enum.ToString()enum.GetNames()enum.GetName()enum.Format()enum.Parse()将枚举转换为字符串。相反,请使用switch语句,并在必要时将名称国际化。

答案 5 :(得分:16)

Enum.GetName(...)

这是最优雅的方法。

var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);

虽然我没有看到调用.ToString()的任何问题,因为它只是更短。

var enumValueString = MyEnum.MyValue.ToString();

使用新的C#6语法,您可以使用:

nameof(MyEnum.MyValue)

答案 6 :(得分:15)

<强> Enum.GetName()

Format()实际上只是GetName()的一个包装器,具有一些格式化功能(或者确切地说是InternalGetValueAsString())。 ToString()Format()几乎相同。我认为GetName()是最好的选择,因为它对于阅读源代码的人来说是完全明显的。

答案 7 :(得分:8)

我创建了一个“描述”扩展方法并将其附加到枚举,以便我可以获得真正用户友好的命名,包括空格和套管。我从来不喜欢将枚举值本身用作可显示的文本,因为它是开发人员用来创建更易读的代码的东西。它不适用于UI显示目的。我希望能够更改UI而无需通过并更改全部的枚举。

答案 8 :(得分:6)

我不知道“首选”方法是什么(询问100个人并得到100个不同的意见)但做最简单和最有效的方法。 GetName有效,但需要更多按键。 ToString()似乎很好地完成了这项工作。

答案 9 :(得分:0)

这也会奏效。

    List<string> names = Enum.GetNames(typeof(MyEnum)).ToList();

答案 10 :(得分:0)

对于VB爱好者:

const DecoratedComponent = withRouter(withStyles(styles)(
  class extends React.Component<IProps & RouteComponentProps<IProps> & WithStyles<withStyleProps>> {
    render() {
      const { classes, text } = this.props;
      return <div className={classes.mainStyle}>{text}</div>;
    }
  }
));

答案 11 :(得分:0)

从可读性的角度来看,

ToString()给出了最多的最明显的结果,而使用Enum.GetName()则需要进行更多的心理分析才能快速了解其操作意图(除非您看到了一直都有这种模式。

从纯性能的角度来看,如@nawfal的答案中所提供的,Enum.GetName()更好。

如果性能确实是您的目标,那么最好事先提供查找(使用Dictionary或其他映射)。

在C ++ / CLI中,这看起来像

Dictionary<String^, MyEnum> mapping;
for each (MyEnum field in Enum::GetValues(MyEnum::typeid))
{
    mapping.Add(Enum::GetName(MyEnum::typeid), field);
}

使用100项枚举和1000000次迭代进行比较:

  

Enum.GetName:〜800ms
  .ToString():〜1600ms
  字典对应时间:〜250ms

答案 12 :(得分:0)

对我来说,将 Enum 转换为 String 的最简单方法是:

requests
//please uncomment the following lines if you need them
//| where timestamp > ago(30d)
//| where cloud_RoleName startswith "slapi-prd"
//| where success == "True" 
| summarize timestamp = max(timestamp) by name, cloud_RoleName

现在要将选定的字符串转换回Enum,您只需解析即可:

// Sample for Enum.ToString(String)
using System;

class Sample
{
    enum Colors {Red, Yellow = 12};

    public static void Main()
    {
    Colors myColor = Colors.Yellow;

    Console.WriteLine("Colors.Red = {0}", Colors.Red.ToString("d"));
    Console.WriteLine("Colors.Yellow = {0}", Colors.Yellow.ToString("d"));

    Console.WriteLine("{0}myColor = Colors.Yellow{0}", Environment.NewLine);

    Console.WriteLine("myColor.ToString(\"g\") = {0}", myColor.ToString("g"));
    Console.WriteLine("myColor.ToString(\"G\") = {0}", myColor.ToString("G"));

    Console.WriteLine("myColor.ToString(\"x\") = {0}", myColor.ToString("x"));
    Console.WriteLine("myColor.ToString(\"X\") = {0}", myColor.ToString("X"));

    Console.WriteLine("myColor.ToString(\"d\") = {0}", myColor.ToString("d"));
    Console.WriteLine("myColor.ToString(\"D\") = {0}", myColor.ToString("D"));

    Console.WriteLine("myColor.ToString(\"f\") = {0}", myColor.ToString("f"));
    Console.WriteLine("myColor.ToString(\"F\") = {0}", myColor.ToString("F"));
    }
}
/*
This example produces the following results:
Colors.Red = 0
Colors.Yellow = 12

myColor = Colors.Yellow

myColor.ToString("g") = Yellow
myColor.ToString("G") = Yellow
myColor.ToString("x") = 0000000C
myColor.ToString("X") = 0000000C
myColor.ToString("d") = 12
myColor.ToString("D") = 12
myColor.ToString("f") = Yellow
myColor.ToString("F") = Yellow
*/ 

答案 13 :(得分:-1)

简单:将名称枚举到List中:

List<String> NameList = Enum.GetNames(typeof(YourEnumName)).Cast<string>().ToList()