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.
is
is usually used for type checking as many have already pointed out in the comments.
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.
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.
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. 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:
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.
For the code which is used in the other answer, this is how the Main
function looks like in the IL:
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.