简体   繁体   English

比较两个字符串与is-operator

[英]Compare two strings with the is-operator

I just realized that you can compare two strings with is 我才意识到,你可以比较两个字符串is

So something like bool areEqual = "" is ""; 所以像bool areEqual = "" is ""; returns true or also 返回true

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

I didn't know this is possible and didn't find any resources on the web. 我不知道这是可能的,并且在网络上找不到任何资源。 Are there any benefits using the is operator over Equals or == ? 使用is运算符比Equals==有什么好处吗?

You can compare a string and a constant using the is pattern , which is new in C# 7. 您可以使用is pattern比较字符串和常量 ,这是C#7中的新增功能。

The most common usage of this pattern will be to do null-checks, without invoking the equality operator. 此模式最常见的用法是执行空检查,而不调用相等运算符。

Take this example: 举个例子:

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);
        }
    }
}

This will output: 这将输出:

==
False
False

meaning, the == operator, comparing a Test and a constant, will only be invoked once. 意思是, ==运算符(将Test和常量进行比较)将仅被调用一次。 When using is , it won't be. 当使用is ,它将不会。 This is handy for checking against null without using ReferenceEquals (though ReferenceEquals is in fact special-handled by the compiler). 这在不使用ReferenceEquals情况下检查null是否很方便(尽管ReferenceEquals实际上是由编译器特殊处理的)。 (see further below for more information). (更多信息请参见下文)。

For strings, however, it has very little benefit as the compiler already does a lot of magic rewriting for you. 但是,对于字符串来说,它没有什么好处,因为编译器已经为您完成了许多魔术重写。

If you use a string instead of the type from my example above, the ceq instruction which is a direct comparison will be done in both cases, even if string has overloaded the == operator. 如果您使用字符串而不是上面示例中的类型,则在两种情况下都将执行直接比较的ceq指令,即使string重载了==运算符。

Edit: As was pointed by @meJustAndrew in the comments, this is because the comparison is done on the reference as though it was of type object , and thus no operators are involved. 编辑:正如@meJustAndrew在评论中指出的,这是因为比较是在引用上完成的,就像它是object类型一样,因此不涉及运算符。 You can see from his answer here, near the bottom, what is actually happening. 您可以从他在底部附近的答案中看到实际发生的情况。 The generated code of test is null is identical to the one from (object)test == null . 生成的test is null代码test is null ,与(object)test == null代码相同。


This particular conversion only holds true for reference types, however. 但是,此特定转换仅适用于引用类型。

If the code in Main above had been 如果上面Main的代码是

var test = (int?)10;

Console.WriteLine(test == null);
Console.WriteLine(test is null);

both would compile to this equivalent code: 两者都将编译为以下等效代码:

Console.WriteLine(test.HasValue == false);

However, this is just another area where there's a lot of compiler magic involved. 但是,这只是涉及很多编译器魔术的另一个领域。

is is usually used for type checking as many have already pointed out in the comments. is通常用于许多在评论中已经指出的类型检查。

For example: 例如:

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

You can of course use it to compare strings or against null, but (and this is going slightly to primary opinion based answer) I would advice against it, because it won't be consistent with most of the projects where you will see string comparisons or null checks. 当然,您可以使用它来比较字符串或与null进行比较,但是(这会稍微影响基于主要观点的答案)我建议您这样做,因为它与大多数项目中您会看到字符串比较的不一致或空检查。

For example, a null check would be if(a != null) or if(a is null) which will drive people to use comparisons in two different ways. 例如,空检查将是if(a != null)if(a is null) ,这将促使人们以两种不同方式使用比较。

EDIT: 编辑:

I have just written a small piece of code in order to see what happens behind the scenes and it seems that it is no difference between using the is operator and classic null checks. 我只是写了一小段代码,以了解幕后发生的事情,看来使用is运算符和经典的null检查之间没有什么区别。 For the following code: 对于以下代码:

object obj = 23;

bool withIs = obj is null;
bool withEquals = obj == null;

The disassembled version from the IL looks like this: IL的反汇编版本如下所示:

object obj = 23;
bool withIs = obj == null;
bool withEquals = obj == null;

So it turns out that the generated IL is the same in the end which once again makes me advise you to use the is operator only for type checks. 因此,事实证明最终生成的IL是相同的,这再次使我建议您仅将is运算符用于类型检查。

For the code which is used in the other answer, this is how the Main function looks like in the IL: 对于其他答案中使用的代码,这是IL中Main函数的外观:

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

You can see that on the last line the test variable has a cast to an object and this is why for the is null comparison, the == operator seems to not be invoked. 您可以看到在最后一行, test变量将object强制转换为object ,这就是为什么在进行is null比较时,似乎未调用==运算符的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM