Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between equal operator and is operator in enums

Tags:

c#

enums

c#-9.0

Given the following enum,

enum ExampleOptions
{
  OptionA,
  OptionB
}

Is there any real difference between these two statements?

ExampleOptions option = ExampleOptions.OptionA;

bool equals1 = option == ExampleOptions.OptionA; // true
bool equals2 = option is ExampleOptions.OptionA; // true

As far as I can see, the only difference between using == and is is mainly that is expects a constant operand (thus, operation order matters).

I used to use the == operator just because I wanted to avoid ugly statements such as
!(option is ExampleOptions.OptionA).
But, after C#9 was released and the is not operator added; I find is/is not a cleaner and more verbose way to write this kind of statements.

Is there any hidden consequence of deciding which operator to use?

like image 696
VRoxa Avatar asked Jul 15 '26 00:07

VRoxa


2 Answers

As far as I can see, the only difference between using == and is is mainly that is expects a constant operand (thus, operation order matters).

There's quite a few more differences, for example is allows you to write statements like:

val is ExampleOptions.OptionA or ExampleOptions.OptionB or ExampleOptions.OptionD

rather than the old fashioned statement with || and repeated naming of your variable.

is also (and this is very important!) doesn't call operator ==, it directly checks the instance. This doesn't apply to enums, but if you have an object with a user-defined == operator that doesn't check for null, var != null will most likely crash with an exception, while var is not null will do as you expect.

like image 139
Blindy Avatar answered Jul 17 '26 13:07

Blindy


As for enum comparisons is seems syntactic sugar.

bool equals1 = option == ExampleOptions.OptionA; // true
bool equals2 = option is ExampleOptions.OptionA; // true

Both statements compile to exactly the same IL (tested in .NET5), they invoke the CIL instruction ceq, which I think stands for equality comparison.
So your assumption that there is no functional difference seems correct.

// [115 13 - 115 61] 
IL_0003: ldloc.0      // option
IL_0004: ldc.i4.0
IL_0005: ceq
IL_0007: stloc.1      // equals1

// [116 13 - 116 61]
IL_0008: ldloc.0      // option
IL_0009: ldc.i4.0
IL_000a: ceq
IL_000c: stloc.2      // equals2
like image 22
lidqy Avatar answered Jul 17 '26 14:07

lidqy