比较两个字符串与is-operator

时间:2019-03-05 08:45:14

标签: c# string string-comparison

我刚刚意识到您可以将两个字符串与is

进行比较

所以类似bool areEqual = "" is "";的返回true还是

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

我不知道这是可能的,并且在网络上找不到任何资源。 与isEquals相比,使用==运算符有什么好处吗?

2 个答案:

答案 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比较,==运算符似乎不会被调用。