Страницы

Поиск по вопросам

среда, 17 октября 2018 г.

Как в C# правильно сравнивать строки

Как в C# правильно сравнивать строки: Equals или ==?
string str1 = "s"; string str2 = "s";
Console.WriteLine("eq: " + str1.Equals(str2)); Console.WriteLine("==: " + (str1 == str2));
В обоих случаях результат True, хотя String является классом и оператор == должен был сравнить ссылки.
IlDasm показал, что создаются 2 переменные и сравниваются согласно методам Equals и == (op_Equality)
IL_0000: nop IL_0001: ldstr "s" IL_0006: stloc.0 IL_0007: ldstr "s" IL_000c: stloc.1 IL_000d: ldstr "eq: " IL_0012: ldloc.0 IL_0013: ldloc.1 IL_0014: callvirt instance bool [mscorlib]System.String::Equals(string) IL_0019: box [mscorlib]System.Boolean IL_001e: call string [mscorlib]System.String::Concat(object, object) IL_0023: call void [mscorlib]System.Console::WriteLine(string) IL_0028: nop IL_0029: ldstr "==: " IL_002e: ldloc.0 IL_002f: ldloc.1 IL_0030: call bool [mscorlib]System.String::op_Equality(string, string) IL_0035: box [mscorlib]System.Boolean IL_003a: call string [mscorlib]System.String::Concat(object, object)


Ответ

В C# правильно сравнивать строки и через ==, и через Equals. Но более предпочтительным будет сравнивать через ==
Почему так?
Метод Equals подразумевает сравнение значений объектов ссылочного типа, он объявлен как virtual и для строк он перегружен и сравнивает их, как и предполагается, по значению. В Ваших классах Вы должны давать свою реализацию для него. Иначе он будет вести себя как ReferenceEquals и для ссылок, которые указывают не на один объект будет давать false, хоть они и будут равны по значению.
Оператор == для строк представляют свою реализацию, отличную от стандартной для всех других объектов ссылочного типа. Если сравниваемые ссылки имеют тип System.String, то он сначала сравнит указывают ли ссылки на один тот же объект и если нет, то будет сравнивать две ссылки типа System.String по значению.
Но маленькое замечание, если мы сравниваем объект типа System.String (string) с объектом типа System.Object (object), который указывает на строку, они будут сравниваться по значениям.
Пример:
string str = "str"; object obj = "str"; bool result = str.Equals(obj);
result будет равен true, так как obj приведётся к типу string, потому что метод Equals мы вызвали у строки (объекта типа string).
Но если мы сравниваем объект типа System.Object (object), который указывает на строку, с объектом типа System.String (string) они будут сравниваться по ссылке.
Пример:
string str = "str"; object obj = "str"; bool result = obj.Equals(str);
result будет равен false, так как str приведётся к типу object, потому что метод Equals мы вызвали у объекта типа object
Поэтому в данном случае важно привести object к типу string

Комментариев нет:

Отправить комментарий