Сравнить 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 60

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)

ref

компилятор обнаружил, что это значение уже находится в памяти, поэтому он назначает ту же ссылку на 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 относятся к различным объектам.

вы пробовали:

Console.WriteLine(y == x.ToString());