使用 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 比较,== 运算符似乎没有被调用。