将枚举转换为字符串

Eri*_*nau 155 .net enums

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

  • Enum.GetName
  • Enum.Format

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

Kei*_*ith 106

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

nameof(MyEnum.EnumValue);

// Ouputs
> "EnumValue"
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这值得更多关注.尽管有明显的限制,即需要编译时输入.在我看来,这应该是首选*尽可能*.'重命名'和'查找所有引用'也会考虑它,可能避免魔术字符串和重复常量. (9认同)
  • 所以我猜在运行时定义枚举值时它不会工作?例如:MyEnum variableEnum; variableEnum = setEnumValueMethod(); 名称(变量枚举); (2认同)
  • @Maxter 不,因为`nameof(variableEnum)` 将是`"variableEnum"`。它反映(在构建时)字段/属性/参数/变量的 _name_ 而不是 _value_。 (2认同)

小智 94

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

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);
}
Run Code Online (Sandbox Code Playgroud)

  • Enum.GetName将值作为对象参数.这意味着该值将被加框,这将浪费分配和垃圾回收上的CPU资源.如果这需要花费很多时间,那么Enum.GetName的吞吐量将远低于缓存字典中的值并在那里查找名称. (6认同)

naw*_*fal 26

在我的测试中,Enum.GetName速度更快,利润率也不错.内部ToString呼叫Enum.GetName. .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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

测试设置:枚举8个值,没有.迭代次数= 1000000

结果:Enum.GetName => 700 ms,ToString => 2000 ms

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

Enum.GetName(typeof(Bla), value)
Run Code Online (Sandbox Code Playgroud)

value.ToString()
Run Code Online (Sandbox Code Playgroud)


Dav*_*ton 20

所有这些内部最终调用一个名为的方法InternalGetValueAsString.之间的差异ToStringGetName将是GetName必须先确认几件事情:

  1. 您输入的类型不为空.
  2. 您输入的类型实际上是枚举.
  3. 传入的值不为null.
  4. 传入的值是枚举实际可以使用的类型,因为它是基础类型或枚举本身的类型.它使用GetType值来检查这个.

.ToString不必担心上述任何问题,因为它是在类本身的实例上调用的,而不是在传入的版本中调用,因此,由于该.ToString方法没有相同的验证问题作为静态方法,我会得出结论,这.ToString是将值作为字符串获取的最快方法.

  • 你在哪里检查这些?装配版是什么?我得到了非常不同的结果. (2认同)

And*_*rei 20

Enum.GetName(...)

这是最优雅的方法.

var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);
Run Code Online (Sandbox Code Playgroud)

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

var enumValueString = MyEnum.MyValue.ToString();
Run Code Online (Sandbox Code Playgroud)

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

nameof(MyEnum.MyValue)
Run Code Online (Sandbox Code Playgroud)


小智 17

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

xml片段中解释,

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


Tam*_*ege 15

Enum.GetName()

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


Dan*_*boo 8

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


小智 6

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