Где == оператор определяется в классе "объект"?
Я искал исходный код FCL, и я смутился, что string.Equals()
использует Object.ReferenceEquals()
, а Object.ReferenceEquals()
использует оператор ==
для jugde. И тогда я не могу найти, как определяется оператор ==
.
Итак, где задан исходный оператор?
Ответы
Ответ 1
Это оператор, используемый языком для проверки того, что два значения одинаковы. Когда ваш код будет скомпилирован, этот оператор будет скомпилирован соответствующим образом в CIL, а затем, когда мы будем выполняться CLR, два значения будут сравниваться, если они будут одинаковыми.
Например, это код CIL для метода Main
:
![Введите описание изображения здесь]()
который компилятор производит для следующей программы (это консольное приложение):
class Program
{
static void Main(string[] args)
{
int a = 3;
int b = 4;
bool areEqual = a == b;
Console.WriteLine(areEqual);
}
}
Обратите внимание на строку IL_0007. Там выдается инструкция ceq
. Это то, что вы ищете, оператор ==
.
Важное примечание
Это происходит, когда ==
не перегружается.
Ответ 2
Если нет перегруженного оператора ==
(как здесь), компилятор выдает команду ceq
. На этом этапе больше нет кода на С#.
Сравнивает два значения. Если они равны, целочисленное значение 1 (int32) помещается в стек оценки; в противном случае 0 (int32) помещается в стек оценки.
Ответ 3
ceq
берет два значения из стека и дает результаты. Если значение результата равно 1, то они считаются равными и 0, если они не равны.
Однако оператор ==
не всегда переводится на ceq
.
Результат ==
в С# в ceq
зависит от некоторых факторов, таких как are data types primitives
или do they have custom == operators
или are they references
.
Ответ 4
Перегрузка operator==
в С# - синтаксический сахар для вызова статической функции. Разрешение перегрузки, как и все разрешения перегрузки, происходит на основе статического типа объекта, а не динамического типа. Давайте снова рассмотрим Object.ReferenceEquals
:
public static bool ReferenceEquals (Object objA, Object objB) {
return objA == objB;
}
Здесь статический тип objA
и objB
равен Object
. Динамический тип может быть любым; строка, какой-либо другой пользовательский тип, что угодно; это не имеет значения. Определение которого operator==
вызывается, статически определяется при компиляции этой функции, поэтому вы всегда получаете по умолчанию, не перегруженные, встроенные в язык..NET мог просто не иметь ReferenceEquals
и позволить пользователям делать ((object)a) == ((object)b)
, но имея определенную именованную функцию, чтобы сказать, что происходит, улучшает ясность.
Object.Equals
, с другой стороны, является просто виртуальной функцией. В результате выбор Equals
основан на динамическом типе объекта слева от .Equals(
, как и любой другой вызов виртуальной функции.