为啥 C# 'is' 运算符在比较两个布尔值时会给出正确的结果,我应该使用它吗?

Posted

技术标签:

【中文标题】为啥 C# \'is\' 运算符在比较两个布尔值时会给出正确的结果,我应该使用它吗?【英文标题】:Why does the C# 'is' operator give a correct result when comparing two boolean values and should I use it?为什么 C# 'is' 运算符在比较两个布尔值时会给出正确的结果,我应该使用它吗? 【发布时间】:2021-11-06 20:05:06 【问题描述】:

我注意到这个is 运算符产生了与== 运算符相同的结果,甚至编译(参见this gist)。鉴于我只能在文档中看到与运行时类型测试相关的内容,这是对 is 运算符的正确用法吗?

bool test = false;

if(!test)

// some code


//OR

if(test is false)

// some code

【问题讨论】:

因为您可以使用is 变量将变量的值与literal 进行比较。我建议不要以这种方式使用它。 查看文档is operator 在这种情况下,这不是 either 运算符的正确用法,在我看来并不那么谦虚。使用if (!test),它们是布尔值是有原因的。 This covers it a little bit @JeroenMostert 这是一个公平的观点。我不会在实际场景中使用它,所以为什么我决定现在这样表示它是一个谜:facepalm:. 【参考方案1】:

它是有效的,因为它是模式匹配功能的一部分。但是正如@Jon Skeet 已经回答的那样,使用它来检查与 bool 变量的相等性是不习惯的。 在 C# 9 中,常见的用例是一次检查多个条件,例如

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

不过,它主要是语法糖。

【讨论】:

【参考方案2】:

是的,它完全有效 - 它是 constant pattern。从这个意义上说,它是“正确的”。这不是编译器的实现细节或错误。

虽然在 if 语句中以这种方式使用它是相当不寻常的 - 常量模式更常用于 switch 语句或表达式。

虽然它们并不完全等效。与is 匹配的模式不会在is 运算符的左侧执行自定义转换。所以举个例子:

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);
    

最后一条语句的错误信息可能有点混乱:

错误 CS0029:无法将类型“bool”隐式转换为“MyBool”

这是由于constant pattern behaviour的这一部分:

当输入值不是开放类型时,将常量表达式隐式转换为匹配表达式的类型;如果输入值的类型与常量表达式的类型不模式兼容,则模式匹配操作是错误的。

有趣的是,如果您添加从boolMyBool 的转换,错误会发生变化:

错误 CS0150:需要一个常数值

但无论如何,从根本上说它是无效的。

【讨论】:

将真/假运算符添加到 MyBool 时甚至无法编译。直到。 (简单地说),另一个区别是MyBool 也可以声明自己的== 运算符,x == true 会调用它,但is 不会。 :) @Sweeper:会添加的,是的。 @Sweeper:实际上,我不会,因为在给定字符串比较的情况下,准确描述它使用的相等概念有点棘手。将按原样离开...

以上是关于为啥 C# 'is' 运算符在比较两个布尔值时会给出正确的结果,我应该使用它吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥要在 C# 中对布尔值使用 |= 运算符?

C#中的==EqualReferenceEqual

C#中的==EqualReferenceEqual

为啥在使用 statsmodels 预测测试值时会收到此 numpy 错误?

为啥在多维数据集中分配值时会产生nan?

为啥 is 运算符在给定 null 时返回 false?