使用 is 运算符比较两个字符串
Compare two strings with the is-operator
我刚刚意识到你可以用 is
比较两个字符串
所以像 bool areEqual = "" is "";
returns true
或者
string x = null;
bool areEqual = x is null;
我不知道这是可能的,也没有在网上找到任何资源。
使用 is
运算符比 Equals
或 ==
有什么好处吗?
您可以使用 is
模式 比较字符串 和常量 ,这是 C# 7 中的新增功能。
此模式最常见的用法是在不调用相等运算符的情况下进行空值检查。
举个例子:
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
时不会。这对于不使用 ReferenceEquals
检查 null
很方便(尽管 ReferenceEquals
实际上是由编译器特殊处理的)。 (有关更多信息,请参阅下文)。
然而,对于字符串,它几乎没有什么好处,因为编译器已经为你做了很多神奇的重写。
如果您使用字符串而不是上面示例中的类型,则在这两种情况下都会执行作为直接比较的 ceq
指令,即使字符串已重载 ==
运算符.
编辑: 正如 @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);
然而,这只是另一个涉及大量编译器魔法的领域。
is
通常用于类型检查,正如评论中已经指出的那样。
例如:
object obj = 23;
bool isInt = obj is int; //this will be true
您当然可以使用它来比较字符串或与 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
比较,==
运算符似乎没有被调用。
我刚刚意识到你可以用 is
所以像 bool areEqual = "" is "";
returns true
或者
string x = null;
bool areEqual = x is null;
我不知道这是可能的,也没有在网上找到任何资源。
使用 is
运算符比 Equals
或 ==
有什么好处吗?
您可以使用 is
模式 比较字符串 和常量 ,这是 C# 7 中的新增功能。
此模式最常见的用法是在不调用相等运算符的情况下进行空值检查。
举个例子:
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
时不会。这对于不使用 ReferenceEquals
检查 null
很方便(尽管 ReferenceEquals
实际上是由编译器特殊处理的)。 (有关更多信息,请参阅下文)。
然而,对于字符串,它几乎没有什么好处,因为编译器已经为你做了很多神奇的重写。
如果您使用字符串而不是上面示例中的类型,则在这两种情况下都会执行作为直接比较的 ceq
指令,即使字符串已重载 ==
运算符.
编辑: 正如 @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);
然而,这只是另一个涉及大量编译器魔法的领域。
is
通常用于类型检查,正如评论中已经指出的那样。
例如:
object obj = 23;
bool isInt = obj is int; //this will be true
您当然可以使用它来比较字符串或与 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
比较,==
运算符似乎没有被调用。