使用is-operator比较两个字符串

问题描述 投票:2回答:2

我刚刚意识到你可以用is比较两个字符串

所以像bool areEqual = "" is "";这样的东西会返回true或者

string x = null;
bool areEqual = x is null;

我不知道这是可能的,也没有在网上找到任何资源。使用is算子比Equals==有什么好处吗?

c# string string-comparison
2个回答
2
投票

您可以使用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时,它不会。这对于在不使用null的情况下检查ReferenceEquals很方便(尽管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);

然而,这只是涉及很多编译魔术的另一个领域。


1
投票

is通常用于类型检查,正如许多人已经在评论中指出的那样。

例如:

object obj = 23;
bool isInt = obj is int; //this will be true

你当然可以用它来比较字符串或者反对null,但是(这会略微以基于意见为主的答案)我建议反对它,因为它与你将看到字符串比较的大多数项目不一致或空检查。

例如,空检查将是if(a != null)if(a is null),它将驱使人们以两种不同的方式使用比较。

编辑:

我刚刚编写了一小段代码,以便了解幕后发生的事情,似乎使用is运算符和经典的null检查没有区别。对于以下代码:

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运算符进行类型检查。

对于在另一个答案中使用的代码,这是IL中Main函数的样子:

    Test test = new Test();
    Console.WriteLine(test == null);
    Console.WriteLine((object)test == null);

您可以看到在最后一行test变量有一个强制转换为object,这就是为什么is null比较,==运算符似乎不被调用。

© www.soinside.com 2019 - 2024. All rights reserved.