为啥 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的这一部分:
当输入值不是开放类型时,将常量表达式隐式转换为匹配表达式的类型;如果输入值的类型与常量表达式的类型不模式兼容,则模式匹配操作是错误的。
有趣的是,如果您添加从bool
到MyBool
的转换,错误会发生变化:
错误 CS0150:需要一个常数值
但无论如何,从根本上说它是无效的。
【讨论】:
将真/假运算符添加到 MyBool 时甚至无法编译。直到。 (简单地说),另一个区别是MyBool
也可以声明自己的==
运算符,x == true
会调用它,但is
不会。 :)
@Sweeper:会添加的,是的。
@Sweeper:实际上,我不会,因为在给定字符串比较的情况下,准确描述它使用的相等概念有点棘手。将按原样离开...以上是关于为啥 C# 'is' 运算符在比较两个布尔值时会给出正确的结果,我应该使用它吗?的主要内容,如果未能解决你的问题,请参考以下文章