使用is运算符比较两个字符串

3
我刚刚意识到可以使用is来比较两个字符串。
因此,像bool areEqual = "" is "";这样的语句会返回true或者其他。请注意保留HTML标记。
string x = null;
bool areEqual = x is null;

我不知道这种做法是可能的,也没有在网上找到任何资源。 使用is运算符是否比使用Equals==更有优势?

最初的回答:


1
使用is进行类型比较,判断变量x是否为字符串类型,结果将赋值给布尔变量isString - undefined
1
is运算符用于检查类型的相等性。由于两个空字符串都具有相同的string类型,该操作将返回true - undefined
1
我不是在谈论比较类型的问题。"" is "x" 返回 False - 所以你的评论是错误的 @TetsuyaYamamoto - undefined
2
жүҖжңүеҸ‘иЎЁжңүе…іisд»…з”ЁдәҺзұ»еһӢжЈҖжҹҘзҡ„иҜ„и®әзҡ„дәәйғҪйңҖиҰҒдәҶи§ЈдёҖдёӢC# 7дёӯзҡ„жЁЎејҸеҢ№й…ҚгҖӮ - undefined
1
x is null 需要使用 C# 7 及以上版本。如果你正在使用 C# 7 或更高版本,那么 if (x is null) 是没有问题的。 - undefined
显示剩余6条评论
2个回答

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指令,即使字符串重载了==运算符也是如此。
编辑:正如@meJustAndrew在评论中指出的那样,这是因为将引用作为object类型进行比较,因此不涉及任何运算符。您可以从他的答案中看到,test is null的生成代码与(object)test == null的生成代码相同。
然而,这种转换仅适用于引用类型。
如果上面的代码是这样的:
var test = (int?)10;

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

两者都会编译成等效的代码:

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

然而,这只是另一个需要大量编译器魔法的领域。最初的回答。

看起来==运算符只会在经典的空检查中被调用一次,而在is null检查中根本不会被调用,但实际上它在两种情况下都会被调用。 - undefined
似乎并不是这样,代码只输出一次==就能明显看出来。 - undefined
看看这个:https://robertwray.co.uk/blog/using-is-instead-of-to-check-whether-an-object-is-a-null-reference - undefined
你看到我下面的答案了吗? - undefined
is只是对object类型调用==,而不是你自定义的类型,这就是为什么你在控制台上看不到它的输出。请至少更新你的回答,以免误导其他读者。 - undefined
is null是编译器的魔法,它取决于情况。没有简单的重写方法,只需将其强制转换为object,然后进行正常比较,因为这会在使用可为空值类型的is null模式时添加装箱操作。换句话说,x is null并不总是被重写为(object)x == null。换句话说,对于引用类型而言你是对的,但在编译器级别上也不是那么简单。 - undefined

1

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

例如:

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

你当然可以使用它来比较字符串或与null进行比较,但是(这是一个基于个人观点的答案),我建议不要这样做,因为它将与大多数项目中看到的字符串比较或null检查不一致。
例如,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运算符。
对于在其他答案中使用的代码,这就是Main函数在IL中的样子:
    Test test = new Test();
    Console.WriteLine(test == null);
    Console.WriteLine((object)test == null);

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接