Сравнить 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 trueIn второй случай, когда вы инициализировали 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 относятся к различным объектам.
