我应该避免使用 C#“is”运算符进行相等检查吗? [关闭]

Posted

技术标签:

【中文标题】我应该避免使用 C#“is”运算符进行相等检查吗? [关闭]【英文标题】:Should I avoid using the C# "is" operator for equality checks? [closed] 【发布时间】:2021-08-21 16:56:37 【问题描述】:

一位同事告诉我,我可以使用 isis not 代替相等运算符 ==!=。我认为is 运算符与类型有关,the official docs on MSDN 同意,但它也指出:

从 C# 7.0 开始,您还可以使用 is 运算符将表达式与模式匹配

我不认为用 is 检查值会起作用,但奇怪的是:

> "tomato" is "apple"
false
> 1 is not 2
true

我认为这是在这里工作的“表达式模式匹配”(?)。我的问题是,既然使用 is 作为相等运算符 (==) 似乎也适用于值,是否有任何理由避免它?将is 用于所有相等性检查是否会很好,性能和可读性都很好?

【问题讨论】:

"tomato" is "apple" 有效,oneStringVariable is otherStringVariable 无效。 is 后面的参数需要是常量或类型。出于这个原因,你最终会写oneStringVariable is "apple"oneStringVariable == otherStringVariable。我认为这个问题可能是基于意见的(可读性),但它已经收到 3 票赞成,所以我可能错了,不会投票结束它。为了保持一致性,您似乎应该使用== 注意第二个操作数必须是常数。例如,如果 s2 是变量,则 s1 is s2 是不合法的。所以,它不能完全取代==。 (仅供参考)。 另一边注:is null== null 更推荐。不过,我会坚持使用== 进行其他平等检查。 啊,谢谢@Llama!我没有意识到右手边必须是一个常数,这就解释了!除非我需要 is 运算符的功能,否则我将坚持使用 == 进行所有相等比较。 除了is null 被推荐而不是== null,此推荐至少部分与对象可以覆盖其Equals 方法这一事实有关。 【参考方案1】:

除了x is null 之外,它们是相同的,并且是常数值的问题。如 cmets 中所述,模式匹配仅适用于常量。检查 null 的特殊情况保证不使用任何重载的相等运算符。我用 ILSpy 进行了交叉检查:

原始源代码:

string tomatoString = "tomato";
object tomatoObj = "tomato";
Console.WriteLine(tomatoString.Equals("tomato"));
Console.WriteLine(tomatoString is "tomato");
Console.WriteLine(tomatoObj is "tomato");
Console.WriteLine("tomato" is "tomato");
Console.WriteLine(tomatoString is null);

用 ILSpy 反编译:

string tomatoString = "tomato";
object tomatoObj = "tomato";
Console.WriteLine(tomatoString.Equals("tomato"));
Console.WriteLine(tomatoString == "tomato");
string text = tomatoObj as string;
Console.WriteLine(text != null && text == "tomato");
Console.WriteLine(value: true);
Console.WriteLine(tomatoString == null);

(为了完整性:注意如果你在两边都用字面量测试它,编译器只会用它的常量结果替换它。注意静态类型会引入必要的空检查)

【讨论】:

以上是关于我应该避免使用 C#“is”运算符进行相等检查吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C# 如何检查空值。 (值为空)或(空 == 值)。我们可以使用`is`运算符而不是==运算符[重复]

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

Python:我应该避免在块内部对变量进行初始化吗?

ECMA6 002 Object.is()

C#如何检查null。 (value为null)或(null == value)。我们可以使用`is`运算符而不是==运算符[重复]

在对列表进行双重递归时,“预检查”是避免添加无类型或空字符串的首选方法吗?