Search code examples
c#stringstring-comparison

Compare two strings with the is-operator


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 == ?


Solution

  • 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.