61
enum MyEnum
{
    Invalid=0,
    Value1=1,
    Value1=2,
}

void main ()
{
    MyEnum e1 = MyEnum.Value1;
    int i1 = 2;

    // Is there any difference how to compare enumEration values with integers?
    if ( e1==(MyEnum)i1 )... // 1st

    if ( (int)e1==i1 )... // 2nd

In each of mentioned cases we have convertion of enum to int or int to enum.

Is there any difference in these conversions (performance, any other)? Or they are exactly the same?

Thanks.

P.S. In current example I compare to 'magic number' but in real application I am getting data from integer field from DB.

Budda
  • 18,015
  • 33
  • 124
  • 206
  • 1
    The enum type is introduced partly to avoid magic numbers. Why do you want to convert it back to integers? – SOUser Mar 11 '11 at 17:19
  • 1
    [Cast Int To Enum](http://stackoverflow.com/questions/29482/cast-int-to-enum-in-c) may be of some help. – Brad Christie Mar 11 '11 at 17:20
  • 11
    Go with the 2nd option. The 1st one can cause an exception if the integer is out of the defined range in your Enumeration. – Justin Mar 11 '11 at 17:21
  • 4
    In current example I compare to 'magic number' but in real application I am getting data from integer field from DB. – Budda Mar 11 '11 at 17:22
  • That's not correct Justin. In C# an enum variable can be legally assigned any number from the base type (usually int) whether defined or not. Linqpad example program, no exception: void Main() { ((Test)500).Dump(); } enum Test { Yes, No } – Stephen Kennedy Aug 28 '14 at 09:05
  • 3
    @XichenLi, There are a case when to use the integer value. this is when you want to check the rank of the Enum parameter, to see if some value is higher/ lower etc. – IFink Jul 16 '15 at 15:51

7 Answers7

19

This can help.

var constant = 1;
if(constant == (int)MyEnum.Valid1){
......
}
Zoe
  • 27,060
  • 21
  • 118
  • 148
Vivek kumar
  • 239
  • 3
  • 7
16

It doesn't matter which you use, they will perform identically. If there is no enum for an integer value, .net creates one at runtime. There can be no exceptions.

However, Xichen Li is correct - why would you want to compare an enum against an integer value?

Melllvar
  • 2,056
  • 4
  • 24
  • 47
  • 6
    .NET doesn't need to "create" a value if it doesn't exist. Basically an enum value knows what type it is, but just contains the bits of the relevant integer. Why would anything need to be created? – Jon Skeet Mar 11 '11 at 17:24
  • Perhaps I didn't express myself correctly; what I was implying was that something like ((MyEnum)5).ToString() will produce what looks like a "new" member of the enum (assuming that MyEnum has no value == 5). – Melllvar Mar 11 '11 at 17:33
  • 2
    Well, it'll return "5"... but I still wouldn't call that process "creating" a new value. It's how ToString behaves, that's all. The code involved in the conversion itself takes *no* account of whether the value is defined in the enum or not. – Jon Skeet Mar 11 '11 at 17:36
  • 2
    I have a use case. The HttpStatusCode enum defined in the framework. I want to check for all values above 400 to handle them in a specific way. – Gilles Apr 28 '14 at 20:44
  • @Melllvar Mono Projects, check the current OS. https://msdn.microsoft.com/de-de/library/3a8hyw88(v=vs.110).aspx just as example – boop Jan 25 '15 at 17:55
  • @Brettetete I don't see how that link is relevant, or how it's related to the conversation. – Melllvar Jan 26 '15 at 06:59
  • @Melllvar example why one wants to compare enum values – boop Jan 27 '15 at 02:13
  • @Brettetete I meant that there's no point to comparing an int against an enum. The link you posted compares enums against other enums - I certainly wouldn't argue against that. – Melllvar Jan 27 '15 at 03:52
  • 3
    Re. "why would you want to compare an enum against an integer value?" e.g. Enums are not valid SQL types. – Zeek2 Jun 23 '21 at 08:11
  • @Zeek2 cane here to say the exact same thing: it's perfectly normal. – Thomas Jan 19 '22 at 13:54
8

I would recommend casting the int to the representative enum value when you read it from the database. This will greatly improve the readability of your code.

enum MyEnum
{
    Invalid=0,
    Value1=1,
    Value1=2,
}

MyEnum dbValue = ReadEnumFromDB();
if(dbValue == MyEnum.Invalid)
{
   ...
}
Sam Trost
  • 2,173
  • 20
  • 26
  • 1
    Readability of dbValue==MyEnum.Invalid is same as intDbValue==(int)MyEnum.Invalid – Budda Mar 11 '11 at 18:24
  • 2
    If that database column is always properly represented by a MyEnum value, when debugging it will be easier to recognize just exactly what it is that int is supposed to represent. – Sam Trost Mar 14 '11 at 13:13
  • @Budda When logically comparing the values, both comparisons are equivalent, but the idea of using `enum` s is for discarding the use of integer values and replace them with more human readable variables. Regading this, the use and comparison of enums is superior to the use and comparison of integer values. – carloswm85 Apr 29 '23 at 01:25
7

They are exactly the same. Displaying the generated IL using the Debug, Windows, Disassembly (Ctrl-Alt-D) gives you:

MyEnum e1 = MyEnum.Value1;
00260834  mov         dword ptr [ebp-3Ch],1  
int i1 = 2;
0026083B  mov         dword ptr [ebp-40h],2  

// Is there any difference how to compare enumEration values with integers?
if (e1 == (MyEnum) i1) 
00260842  mov         eax,dword ptr [ebp-3Ch]  
00260845  cmp         eax,dword ptr [ebp-40h]  
00260848  sete        al  
0026084B  movzx       eax,al  
0026084E  mov         dword ptr [ebp-44h],eax  
00260851  cmp         dword ptr [ebp-44h],0  
00260855  je          00260858  
; // 1st
00260857  nop  

if ((int)e1 == i1)
00260858  mov         eax,dword ptr [ebp-3Ch]  
0026085B  cmp         eax,dword ptr [ebp-40h]  
0026085E  sete        al  
00260861  movzx       eax,al  
00260864  mov         dword ptr [ebp-48h],eax  
00260867  cmp         dword ptr [ebp-48h],0  
0026086B  je          0026086E  
; // 2nd
0026086D  nop  
David Rogers
  • 4,010
  • 3
  • 29
  • 28
4

I would go with the 2nd method. To me, it makes more logical sense. It would eliminate runtime exceptions if i2 is out of range.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • 3
    There wouldn't be a runtime exception. Any `int` (or matched intergral type if the enum base is changed) may be cast to that enum. – Matthew Whited Mar 11 '11 at 17:22
  • This answer implies that there will be an exception if `i1` is 10, for example. There won't be. – Jon Skeet Mar 11 '11 at 17:23
  • What happens when you cast it? `var newEnum = (MyEnum)10;` - what will `newEnum` be? – Daniel A. White Mar 11 '11 at 17:24
  • 2
    @Daniel: It will be a value of type MyEnum with an underlying value of 10. What happens next depends on what you do with it. If you call ToString, it will just return "10" for example. But there won't be an exception. – Jon Skeet Mar 11 '11 at 17:26
  • 4
    I wish it was a runtime exception. – Daniel A. White Mar 11 '11 at 17:27
  • 1
    @Daniel: Sure, I wish that at least there *was* support for a restricted set of values too, potentially *as well* as the existing "named number" approach that C# actually takes. – Jon Skeet Mar 11 '11 at 17:37
1

Enumerations in .Net are really just pretty meta-structures over the base integral type. (By default that type is int.) If you look at the Generated IL for an enumeration you will find it is really a standard type with several static fields for each of the particular enumeration elements. As such the enum can be cast between integral types transparently.

Related answer

Community
  • 1
  • 1
Matthew Whited
  • 22,160
  • 4
  • 52
  • 69
1

Maybe you could just declare your enum as a static class with all of the possible values being static ints

public static class myEnum{
public static int myInt = 1;
public static int myInt2 = 2;
}

Then compare them directly
int myComparedVar = 2;
if(myComparedVar == myEnum.myInt){...}