在.NET 3.5中将枚举转换为字符串的首选方法是哪种?
- 枚举
- 枚举格式
- ToString
为什么我要选择其中之一?一个人表现更好吗?
在.NET 3.5中将枚举转换为字符串的首选方法是哪种?
为什么我要选择其中之一?一个人表现更好吗?
Answers:
从C#6开始,获取枚举名称的最佳方法是new nameof
运算符:
nameof(MyEnum.EnumValue);
// Ouputs
> "EnumValue"
这在编译时有效,枚举被编译结果中的字符串替换,这意味着这是最快的方法。
如果您认为混淆枚举名称是有价值的或重要的,则枚举名称的任何使用都会干扰代码的混淆,这可能是另一个问题。
nameof(variableEnum)
将是"variableEnum"
。它(在生成时)反映字段/属性/参数/变量的名称而不是值。
"someEnumValue"
,而您需要nameof(SomeEnum.FooBar)
获取"FooBar"
。
适用于我们的项目...
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);
}
在我的测试中,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);
}
}
我不能说这是确定的原因,但是测试表明一个比另一个要快。这两个调用都涉及装箱(实际上,它们是反射调用,实际上是在检索字段名称),并且喜欢起来可能很慢。
测试设置:具有8个值的枚举,否。迭代次数= 1000000
结果:Enum.GetName => 700 ms,ToString => 2000 ms
如果速度不明显,那么我将不在乎和使用ToString
它,因为它可以提供更加清晰的通话。对比
Enum.GetName(typeof(Bla), value)
与
value.ToString()
所有这些最终在内部调用了称为的方法InternalGetValueAsString
。ToString
和之间的区别GetName
是GetName
必须首先验证以下几点:
GetType
该值进行检查。.ToString
不必担心上述任何问题,因为它是在类本身的实例上调用的,而不是在传入版本中调用的,因此,由于该.ToString
方法没有相同的验证问题作为静态方法,我将得出结论,这.ToString
是将值作为字符串获取的最快方法。
最好的发现是MSDN上的这个不相关的问题,其中包含一个可回答该问题的XML代码段。这些方法中的任何一个都有相同的缺陷:它们调用enum.toString()
,使用Dotfuscation时无法正常工作。其他问题似乎与间接装箱(GetName和Format)有关。不幸的是,我找不到使用以上任何一种性能的原因。
从xml代码段改写,
将装箱的枚举传递给string.Format()或任何其他函数都可能导致
enum.ToString()
被调用。点混淆时会引起问题。你不应该使用enum.ToString()
,enum.GetNames()
,enum.GetName()
,enum.Format()
或enum.Parse()
以枚举转换为字符串。而是使用switch语句,并在必要时还对名称进行国际化。
Enum.GetName()
Format()
实际上只是GetName()
一些格式化功能的包装(InternalGetValueAsString()
确切地说是)。ToString()
与几乎相同Format()
。我认为这GetName()
是最好的选择,因为对于任何阅读源的人来说,这样做是显而易见的。
我不知道“首选”方法是什么(问100个人并获得100种不同的意见),但是却做了最简单,最有效的方法。 GetName
可以,但是需要更多的击键。 ToString()
似乎做得很好。
ToString()
从可读性的角度来看,它提供了最明显的结果,而使用则Enum.GetName()
需要更多的心理分析才能快速了解其尝试执行的操作(除非您始终看到该模式)。
从纯性能的角度来看,@ nawfal的答案已经提供了Enum.GetName()
更好的方法。
如果性能确实是您的目标,那么最好事先提供查找(使用字典或其他映射)。
在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