• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Тип String: Operator == и Equals()

  • Автор темы Glucklich
  • Дата начала
G

Glucklich

Если посмотреть в реализацию оператора == типа String можно увидеть следующее:

Код:
public static bool operator ==(string a, string b)
{
return Equals(a, b);
}

Реализация Equals следующая:

Код:
public static bool Equals(string a, string b)
{
return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b)));
}

Видно, что внутри присутстсвует оператор ==.
Так вот почему не происходит зацикливаение?

В моем примере кидает исключение StackOverflowException:

Код:
class Class1
{
public static bool operator ==(Class1 a, Class1 b)
{
return Equals(a, b);
}

public static bool operator !=(Class1 a, Class1 b)
{
return !Equals(a, b);
}

public static bool Equals(Class1 a, Class1 b)
{
return ((a == b) || ((a != null) && (b != null)));
}
}

Ну и где-то вызов:

Код:
private void button1_Click(object sender, EventArgs e)
{
Class1 a = new Class1();
Class1 b = new Class1();
MessageBox.Show((a == b).ToString());
}

В чем прикол?
 
M

mr_ST

Обрати внимание что в коде восстановленном рефлектором нет никакого оператора ==, есть только public static bool op_Equality(string a, string b ). То бишь, вот здесь return ((a == b ) || (((a != null) && (b != null)) && EqualsHelper(a, b ))); происходит сравнение референсов, а не вызов оператора сравнения.
 
G

Glucklich

Понимаю куда вы клоните, однако, как в приведенном мной примере добиться того же результата. Рефлектор восстанавливает точно такой же код как в случае и со String
 
M

mr_ST

Понимаю куда вы клоните, однако, как в приведенном мной примере добиться того же результата. Рефлектор восстанавливает точно такой же код как в случае и со String

Вместо == используйте object.ReferenceEquals(a, b );
 
P

Pasha

Glucklich
Это ошибка в рефлекторе. Код сравнения в String.Equals примерно такой:
Код:
	L_0000: ldarg.0 
L_0001: ldarg.1 
L_0002: bne.un.s L_0006
- тупое сравнение двух unsigned integer.
При компиляции твоего кода получается что-то вроде
Код:
	L_0001: ldarg.0 
L_0002: ldarg.1 
L_0003: call bool ClassLibrary2.Class1::op_Equality(class ClassLibrary2.Class1, class ClassLibrary2.Class1)
- Вызов оператора. Оба случая рефлектор показывает как ==.
 
G

Glucklich

Интересно, сколько еще там глюков?
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!