简体   繁体   English

.NET C#switch语句字符串比较与枚举比较

[英].NET C# switch statement string compare versus enum compare

I'm interested in both style and performance considerations. 我对样式和性能方面的考虑都很感兴趣。 My choice is to do either of the following ( sorry for the poor formatting but the interface for this site is not WYSIWYG ): 我的选择是执行以下任一操作(抱歉格式不佳,但此网站的界面不是WYSIWYG):

One: 一:

string value = "ALPHA";

switch ( value.ToUpper() )
{
   case "ALPHA":
     // do somthing
     break;
   case "BETA":
     // do something else
     break;
   default:
     break;
}

Two: 二:

public enum GreekLetters
{
    UNKNOWN= 0,
    ALPHA= 1,
    BETA = 2,
    etc...

}

string value = "Alpha";
GreekLetters letter = (GreekLetters)Enum.Parse( typeof( GreekLetters ), value.ToUpper() );

switch( letter )
{
   case GreekLetters.ALPHA:
      // do something
      break;
   case GreekLetters.BETA:
      // do something else
      break;
   default:
      break;
}

Personally, I prefer option TWO below, but I don't have any real reason other than basic style reasons. 就个人而言,我更喜欢下面的选项TWO,但除了基本的风格原因之外我没有任何其他真正的理由。 However, I'm not even sure there really is a style reason. 但是,我甚至不确定是否存在风格原因。 Thanks for your input. 感谢您的输入。

The second option is marginally faster, as the first option may require a full string comparison. 第二个选项略快,因为第一个选项可能需要完整的字符串比较。 The difference will be too small to measure in most circumstances, though. 但是,在大多数情况下,差异太小,无法衡量。

The real advantage of the second option is that you've made it explicit that the valid values for value fall into a narrow range. 第二个选项的真正优势在于您明确表示值的value属于窄范围。 In fact, it will throw an exception at Enum.Parse if the string value isn't in the expected range, which is often exactly what you want. 实际上,如果字符串值不在预期范围内,它将在Enum.Parse抛出异常,这通常正是您想要的。

Option #1 is faster because if you look at the code for Enum.Parse , you'll see that it goes through each item one by one, looking for a match. 选项#1更快,因为如果你查看 Enum.Parse 的代码 ,你会看到它逐个遍历每个项目,寻找匹配。 In addition, there is less code to maintain and keep consistent. 此外,维护和保持一致的代码更少。

One word of caution is that you shouldn't use ToUpper , but rather ToUpperInvariant() because of Turkey Test issues. 需要注意的一点是,由于土耳其测试问题,您不应该使用ToUpper ,而应使用ToUpperInvariant()

If you insist on Option #2, at least use the overload that allows you to specify to ignore case. 如果您坚持选项#2,至少使用允许您指定忽略大小写的重载。 This will be faster than converting to uppercase yourself. 这比自己转换为大写更快。 In addition, be advised that the Framework Design Guidelines encourage that all enum values be PascalCase instead of SCREAMING_CAPS. 此外,请注意, 框架设计指南鼓励所有枚举值为PascalCase而不是SCREAMING_CAPS。

I can't comment on the performance part of the question but as for style I prefer option #2. 我不能评论问题的性能部分,但至于风格我更喜欢选项#2。 Whenever I have a known set of values and the set is reasonably small (less than a couple of dozen or so) I prefer to use an enum. 每当我有一组已知值并且该集合相当小(少于几十个)时,我更喜欢使用枚举。 I find an enum is a lot easier to work with than a collection of string values and anyone looking at the code can quickly see what the set of allowed values is. 我发现枚举比字符串值的集合更容易使用,任何查看代码的人都可以快速查看允许值的集合。

This actually depends on the number of items in the enum, and you would have to test it for each specific scenario - not that it is likely to make a big difference. 这实际上取决于枚举中的项目数量,您必须针对每个特定场景测试它 - 而不是它可能会产生很大的不同。 But it is a great question. 但这是一个很好的问题。

With very few values, the Enum.Parse is going to take more time than anything else in either example, so the second should be slower. 只有很少的值,Enum.Parse在任何一个例子中都会比其他任何东西花费更多的时间,所以第二个应该更慢。

With enough values, the switch statement will be implemented as a hashtable, which should work the same speed with strings and enums, so again, Enum.Parse will probably make the second solution slower, but not by relatively as much. 有了足够的值,switch语句将被实现为一个哈希表,它应该与字符串和枚举的速度相同,所以再次,Enum.Parse可能会使第二个解决方案变慢,但不会相对多。

Somewhere in the middle, I would expect the cost of comparing strings being higher than comparing enums would make the first solution faster. 在中间的某个地方,我预计比较字符串高于比较枚举的成本将使第一个解决方案更快。

I wouldn't even be surprised if it were different on different compiler versions or different options. 如果它在不同的编译器版本或不同的选项上有所不同,我甚至不会感到惊讶。

I would definitely say #1. 我肯定会说#1。 Enum.Parse() causes reflection which is relatively expensive. Enum.Parse()导致相对昂贵的反射。 Plus, Enum.Parse() will throw an Exception if its not defined and since there's no TryParse() you'd need to wrap it in Try/Catch block 另外,如果没有定义,Enum.Parse()将抛出异常,因为没有TryParse(),你需要将它包装在Try / Catch块中

Not sure if there is a performance difference when switching on a string value versus an enum. 打开字符串值与枚举值时,不确定是否存在性能差异。

One thing to consider is would you need the values used for the case statements elsewhere in your code. 需要考虑的一件事是你需要在代码中的其他地方使用case语句的值。 If so, then using an enum would make more sense as you have a singular definition of the values. 如果是这样,那么使用枚举会更有意义,因为你有一个单一的值定义。 Const strings could also be used. 也可以使用Const字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM