简体   繁体   中英

Why does the C# 'is' operator give a correct result when comparing two boolean values and should I use it?

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
}

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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