Как проверить равенство в штучной упаковке объектов типов значений, когда типы разные, но совместимы для сравнения значений
Когда мы помечаем два типа значений (которые являются различными типами, но совместимы для сравнения значений, например: int и short) и пытаемся вызвать метод Equals, который дает false, даже если значения одинаковы.
Случай 1:
int a = 5;
short b = 5;
var ob_a = (object) a;
var ob_b = (object) b;
var result = a == b; // true
var result_for_objects = ob_a.Equals(ob_b); // false
С другой стороны, когда оба типа значений одинаковы, Equals возвращает фактический результат сравнения значений.
Случай 2:
int a = 5;
int b = 5;
var ob_a = (object) a;
var ob_b = (object) b;
var result = a == b; // true
var result_for_objects = ob_a.Equals(ob_b); // true
Я сравнил оба кода разборки для обоих случаев, но это было то же самое, я не смог найти никакой разницы.
var result = a == b;
012404DE mov eax,dword ptr [ebp-40h]
012404E1 cmp eax,dword ptr [ebp-44h]
012404E4 sete al
012404E7 movzx eax,al
012404EA mov dword ptr [ebp-50h],eax
var result_for_objects = ob_a.Equals(ob_b);
012404ED mov ecx,dword ptr [ebp-48h]
012404F0 mov edx,dword ptr [ebp-4Ch]
012404F3 mov eax,dword ptr [ecx]
012404F5 mov eax,dword ptr [eax+28h]
012404F8 call dword ptr [eax+4]
012404FB mov dword ptr [ebp-5Ch],eax
012404FE movzx eax,byte ptr [ebp-5Ch]
01240502 mov dword ptr [ebp-54h],eax
- Если типы значений внутри упакованных объектов не совпадают, какой метод Equals фактически вызывается?
- Когда оба типа значений внутри упакованных объектов одинаковы, как вызывается метод Equals этого типа значений?
1 ответ
Тип переменной хранится в объекте.
Например:
Console.Write(ob_a.GetType().ToString()); // will give you System.Int32
Console.Write(ob_b.GetType().ToString()); // will give you System.Int16
Это дает различные хэш-коды также с методом: GetHashCode()
Если вы преобразуете короткую переменную в int или другим способом, она будет одинаковой... Таким образом, в основном проблема заключается в различных типах переменных.
Вот ответ на оба вопроса: http://www.ikriv.com/dev/dotnet/ObjectEquality.html
Поскольку вызов Equals() является виртуальным, точная версия метода, который будет вызываться с помощью x.Equals(y), определяется динамическим типом x, который обычно не известен во время компиляции. Также обратите внимание, что в отличие от a==b, выражение x.Equals(y) по своей сути асимметрично. Только x указывает, какая версия Equals() будет вызвана. у вас нет абсолютно никакого права голоса в этом вопросе.