9

Id noticed that this is operator produces the same results and even compiles the same (see this gist) as the == operator. Is this a correct usage of the is operator given that I can only see things related to runtime type-testing in the docs?

bool test = false;

if(!test)
{
// some code
}

//OR

if(test is false)
{
// some code
}
PontiusTheBarbarian
  • 1,004
  • 9
  • 17

2 Answers2

20

Yes, it's completely valid - it's a constant pattern. In that sense, it's "correct". It's not an implementation detail or bug on the part of the compiler.

It's fairly unconventional to use it this way within an if statement though - constant patterns are more commonly used in switch statements or expressions.

They're not completely equivalent though. Pattern matching with is doesn't perform custom conversions on the left-hand side of the is operator. So take this example:

using System;
using System.Text;

struct MyBool
{
    public bool Value { get;}
    
    public MyBool(bool value) => Value = value;
    
    public static implicit operator bool(MyBool value) => value;
}

class Test
{
    static void Main()
    {
        MyBool x = new MyBool(true);
        // Valid: uses the implicit conversion from MyBool to bool
        Console.WriteLine(x == true);
        // Invalid
        Console.WriteLine(x is true);
    }
}

The error message for the last statement is perhaps a little confusing:

error CS0029: Cannot implicitly convert type 'bool' to 'MyBool'

That's due to this part of the constant pattern behaviour:

When the input value is not an open type, the constant expression is implicitly converted to the type of the matched expression; if the type of the input value is not pattern-compatible with the type of the constant expression, the pattern-matching operation is an error.

Interestingly, if you add a conversion from bool to MyBool, the error changes:

error CS0150: A constant value is expected

But fundamentally it's not valid, anyway.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

It is valid, because it is part of pattern matching feature. But as @Jon Skeet already answered, it is not conventional to use it to check equality with bool variables. In C# 9, it's common use case is checking multiple conditions at once, like

int x = Random.Next(50);
if (x is >5 and <17)
//do something

It's syntactic sugar mostly though.

Zadir7
  • 1