Сравнить String и Object в C#
посмотреть этот код:
object x = "mehdi emrani";
string y = "mehdi emrani";
Console.WriteLine(y == x);
возвращает true
.
но этот код:
object x = "mehdi emrani";
string y = "mehdi ";
y += "emrani";
Console.WriteLine(y == x);
возвращает false
.
поэтому, когда я сравниваю строку и объект в первом коде, я получаю true
.
Но когда я сравниваю их во втором коде, я получаю false
.
обе строки одинаковы, но почему, когда я добавляю к строке, мой результат возвращает false
?
6 ответов:
в каждом случае второй операнд
==
иx
типаobject
. Это означает, что вы используете обычный оператор равенства ссылок.теперь в первом случае, вы используете две строки константы С тем же самым содержанием. Компилятор C# будет использовать один объект для этих двух ссылок. Во втором случае,
x
иy
см. отдельные строковые объекты с одинаковым содержимым. Две ссылки будут разными, так что==
возвратит false.вы можете исправить сравнения:
использовать - это переопределяется by
string
(вместо==
оператор, который только перегружен:Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x)
использовать статический!--11--> метод может быть полезен, если любой из аргументов может быть пустым; это означает, что вам не нужно беспокоиться о
NullReferenceException
.сделать обе переменные типа
string
, в котором==
перегрузка в пределахstring
будет выбран во время компиляции, и эта перегрузка сравнивает содержимое строк, а не только ссылкистоит отметить, что дело не только в том, что строковые литералы сами по себе замечаются компилятором C# - речь идет о выражениях констант времени компиляции. Так например:
object x = "mehdi emrani"; string y = "mehdi " + "emrani"; Console.WriteLine(y == x); // True
здесь
y
инициализируется с помощью двух строковых литералов, которые не то же самое, что используется для инициализацииx
, но конкатенация строк выполняется компилятором, который понимает, что это та же строка, которая уже используется дляx
.
при инициализации
object x = "mehdi emrani"; //pointer(x)
он инициализировал его в памяти и назначил ссылку на x. После этого при инициализации
string y = "mehdi emrani"; //pointer(x)
компилятор обнаружил, что это значение уже находится в памяти, поэтому он назначает ту же ссылку на y.
теперь
==
оператор equal, который фактически сравнивает адреса вместо значения, находит один и тот же адрес для обеих переменных, что приводит к true:x==y //actually compares pointer(x)==pointer(x) which is true
In второй случай, когда вы инициализировали x и y, которым назначаются разные адреса.
object x = "mehdi emrani"; //Pointer(x) string y = "mehdi "; //not found in memory y += "emrani"; //Pointer(y)
теперь сравнение найти разные адреса, которые приводят к ложным:
x == y //is actually Pointer(x) == Pointer(y) which is false
так что для преодоления этого вам нужно использовать .Equals (), который вместо ссылки сравнивает значение и тип объекта.
Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true
скорее всего, ссылки сравниваются (стандарт
Equals
реализации объекта). В первом примере C# оптимизирует постоянные строки, и поэтому y и x фактически указывают на один и тот же объект, следовательно, их ссылка равна. В другом случае y создается динамически, и поэтому ссылка отличается.
в фоновом режиме новая строка создается каждый раз, когда вы изменяете существующую, потому что строки являются неизменными, что означает, что они не могут изменить.
см. следующее объяснение:почему строка .NET является неизменяемой?
в первом случае .NET выполняет оптимизацию константы строки и выделяет только один экземпляр строки. И x, и y указывают на один и тот же объект (обе ссылки равны).
но во втором случае x и y указывают на разные экземпляры строк. Добавление "ermani" в y создает третий строковый объект.
оператор"== " в основном возвращает true, если операнды с обеих сторон ссылаются на один и тот же объект. В первом случае x и y относятся к одному и тому же объекту, а во втором случае x & y относятся к различным объектам.