我刚刚意识到您可以将两个字符串与is
所以类似bool areEqual = "" is "";
的返回true
还是
string x = null;
bool areEqual = x is null;
我不知道这是可能的,并且在网络上找不到任何资源。
与is
或Equals
相比,使用==
运算符有什么好处吗?
答案 0 :(得分:2)
您可以使用C#7中新增的is
模式比较字符串和常量。
此模式最常见的用法是执行空检查,而不调用相等运算符。
以这个例子为例:
using System;
public class Program
{
public static void Main()
{
var test = new Test();
Console.WriteLine(test == null);
Console.WriteLine(test is null);
}
public class Test
{
public static bool operator ==(Test a, Test b)
{
Console.WriteLine("==");
return ReferenceEquals(a, b);
}
public static bool operator !=(Test a, Test b)
{
Console.WriteLine("!=");
return !ReferenceEquals(a, b);
}
}
}
这将输出:
==
False
False
意思是,==
运算符将Test
与常量进行比较,将仅被调用一次。使用is
时不会。这对于在不使用null
的情况下检查ReferenceEquals
很方便(尽管ReferenceEquals
实际上是由编译器特殊处理的)。 (有关更多信息,请参见下文)。
但是,对于字符串来说,它没有什么好处,因为编译器已经为您完成了许多魔术重写。
如果使用字符串代替上面示例中的类型,则在两种情况下都将执行直接比较的ceq
指令,即使string重载了==
运算符。 / p>
编辑:正如@meJustAndrew在评论中所指出的,这是因为比较是在引用上完成的,就好像它是object
类型的一样,因此没有涉及运营商。您可以从他在底部附近的答案中看到实际发生的情况。 test is null
生成的代码与(object)test == null
中生成的代码相同。
此特定转换仅适用于引用类型。
如果上面Main
中的代码已经
var test = (int?)10;
Console.WriteLine(test == null);
Console.WriteLine(test is null);
两者都将编译为以下等效代码:
Console.WriteLine(test.HasValue == false);
但是,这只是涉及很多编译器魔术的另一个领域。
答案 1 :(得分:1)
is
通常用于类型检查,正如评论中已经指出的那样。
例如:
object obj = 23;
bool isInt = obj is int; //this will be true
您当然可以使用它来比较字符串或将其与null进行比较,但是(并且这会稍微基于基于主意见的答案)我建议您这样做,因为它与您将要使用的大多数项目不一致查看字符串比较或null检查。
例如,空检查将是if(a != null)
或if(a is null)
,这将促使人们以两种不同方式使用比较。
编辑:
我只写了一小段代码是为了了解幕后发生的事情,看来使用is
运算符和经典的空值检查之间没有什么区别。对于以下代码:
object obj = 23;
bool withIs = obj is null;
bool withEquals = obj == null;
IL的反汇编版本如下:
object obj = 23;
bool withIs = obj == null;
bool withEquals = obj == null;
因此,最终生成的IL相同,这再次使我建议您仅将is
运算符用于类型检查。
对于其他答案中使用的代码,这就是Main
函数在IL中的样子:
Test test = new Test();
Console.WriteLine(test == null);
Console.WriteLine((object)test == null);
您可以看到,在最后一行,test
变量已强制转换为object
,这就是为什么对于is null
比较,==
运算符似乎不会被调用。