I just realized that you can compare two strings with is
So something like bool areEqual = "" is "";
returns true
or also
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 ==
?
You can compare a string and a constant using the is
pattern, which is new in 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. When using is
, it won't be. This is handy for checking against null
without using ReferenceEquals
(though ReferenceEquals
is in fact special-handled by the compiler). (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.
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. 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
.
This particular conversion only holds true for reference types, however.
If the code in Main
above had been
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.