Сравните две строки с оператором is - PullRequest
0 голосов
/ 05 марта 2019

Я только что понял, что вы можете сравнить две строки с is

Так что-то вроде bool areEqual = "" is ""; возвращает true или также

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

Я не знал, что этовозможно и не нашел никаких ресурсов в сети.Есть ли какие-либо преимущества использования оператора is над Equals или ==?

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

is обычно используется для проверки типа, как многие уже указали в комментариях.

Например:

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

Вы, конечно, можете использовать его для сравнения строк илипротив нуля, но (и это немного идет к основному ответу, основанному на мнении), я бы посоветовал против него, потому что это не будет соответствовать большинству проектов, где вы увидите сравнение строк или проверки на ноль.

Например, нулевой проверкой будет if(a != null) или if(a is null), которая заставит людей использовать сравнения двумя различными способами.

РЕДАКТИРОВАТЬ:

Я только чтонаписал небольшой фрагмент кода, чтобы увидеть, что происходит за кулисами, и кажется, что нет никакой разницы между использованием оператора is и классическими проверками нуля.Для следующего кода:

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 оператор ==, похоже, не вызывается.

0 голосов
/ 05 марта 2019

Вы можете сравнить строку и константу , используя шаблон is , который является новым в C # 7.

Наиболее распространенное использование этого шаблонабудет делать нулевые проверки, не вызывая оператор равенства.

Возьмите этот пример:

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

, означающее, что *Оператор 1016 *, сравнивающий Test и константу, будет вызван только один раз.При использовании is не будет.Это удобно для проверки по null без использования ReferenceEquals (хотя ReferenceEquals фактически специально обрабатывается компилятором).(см. далее ниже для получения дополнительной информации).

Однако для строк это дает очень мало преимуществ, так как компилятор уже делает много магического переписывания для вас.

Если вы используете строку вместотипа из моего примера выше, инструкция ceq, которая является прямым сравнением, будет выполнена в обоих случаях, даже если строка перегружена оператором ==.

Редактировать: Как было отмечено @ meJustAndrew в комментариях, это потому, что сравнение выполняется по ссылке, как если бы она была типа object, и, следовательно, операторы не задействованы.Из его ответа вы можете увидеть здесь, внизу, что на самом деле происходит.Сгенерированный код test is null идентичен коду из (object)test == null.


Однако это конкретное преобразование выполняется только для ссылочных типов.

Если код в Main выше было

var test = (int?)10;

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

оба скомпилировали бы в этот эквивалентный код:

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

Однако, это просто еще одна область, где задействовано много магии компилятора.

...