4

Assume we have statement like this:

enum EngineType
{
   Gasoline,
   Diesel,
   Electric
}

var engine = EngineType.Electric;

if (engine is EngineType.Electric)
{
    // do something
}

Why does if statement is true. From microsoft documentation: The is operator checks if the result of an expression is compatible with a given type.

Isn't the left value type of EngineType (enum) and right value type of integer? Am I missing something?

fnsky
  • 41
  • 2
  • Which version are you using? Attempting to compile your example results in a "The type name 'Electric' does not exist in the type 'EngineType'" compilation error, which I would expect since `EngineType.Electric` is not a type. – Lee Nov 12 '19 at 12:53
  • @Lee I'm working with VS2019 C#7.0 so that must be it. – fnsky Nov 12 '19 at 12:56
  • C# pattern matching in action? – Tanveer Badar Nov 12 '19 at 13:03
  • 2
    @TanveerBadar: Precisely. This is a constant pattern. – Jon Skeet Nov 12 '19 at 13:08
  • [I can't get this to compile](https://dotnetfiddle.net/Qlovb9), it is explicitly breaking on the `is MyEnum.MyValue` syntax. Am I missing something or is this not valid syntax? – Flater Nov 12 '19 at 13:34
  • @Flater That is not true. The only requirement is a compiler that supports C# 7.0. You can even use this syntax in a .NET Framework 2.0 project as long as you're using a recent compiler. (Try it out yourself with VS2019) – Herohtar Nov 12 '19 at 21:26

3 Answers3

2

Because when you use the is keyword this way, you are actually doing Pattern Matching (starting with C# 7.0) :

Constant pattern, which tests whether an expression evaluates to a specified constant value.

Martin Verjans
  • 4,675
  • 1
  • 21
  • 48
  • @Flater False. You can use this in a .NET Framework that targets even as far back as .NET 2.0 if you wanted. You just have to be using a compiler that supports C# 7.0. – Herohtar Nov 12 '19 at 21:25
  • @Herohtar: Dotnetfiddle runs .Net 4.7.3 though so I'm expecting it to be C#7.3 (same release). But Dotnetfiddle doesn't explicitly mention the C# version, granted. – Flater Nov 12 '19 at 21:28
  • 1
    @Flater There's no telling what Dotnetfiddle is running behind the scenes, so you can't base anything on what does or doesn't work there. I can confirm that the syntax works when I create a .NET Framework 2.0 project using Visual Studio 2019. – Herohtar Nov 12 '19 at 21:32
1

Because is in C# 7.0 supports pattern matching. In particular, it allows matching against a "constant pattern". To quote from the documentation (emphasis mine):

When performing pattern matching with the constant pattern, is tests whether an expression equals a specified constant. In C# 6 and earlier versions, the constant pattern is supported by the switch statement. Starting with C# 7.0, it's supported by the is statement as well. Its syntax is:

expr is constant

where expr is the expression to evaluate, and constant is the value to test for. constant can be any of the following constant expressions:

  • A literal value.

  • The name of a declared const variable.

  • An enumeration constant.

Heinzi
  • 167,459
  • 57
  • 363
  • 519
0

Enums are full types. While internally they are represented and can be (implicitly?) cast into integers (the number type they use/equate to can be changed), they are each a distinct type.

This actually enables all those Additional typecheks that make them useful. We recently had a Question about why we do not just use int constants over Enums:

Another enum vs. int

is compares types and only types. If you do not give it a type, it will just go and find the type of what you did give it. With the values primitive types it can be ambigious. It is a compiler/runtime detail if 1 is a Int16, Int32 or Int64 today. Indeed it will likely varry on the digit lenght of the constant I give it. Not something I can rely on.

It could propably tell you that 1.2 is not the same as type 1 (unless some braindead designer decided to use decimal or float values in both cases for once).

But all possible values of the type EngineType are of the type EngineType. That is a big reasons Enums are a thing in the first place. Exactly to allow such type checks.

Christopher
  • 9,634
  • 2
  • 17
  • 31
  • 3
    Enums are types but `EngineType.Electric` is not a type so this doesn't fully answer the question. – Lee Nov 12 '19 at 12:55