Ответ 1
Выражение
q.Contains(s)
ищет элемент q
, для которого EqualityComparer<object>.Default
.Equals(element, s)
истинно. Для примитивов в штучной упаковке это сравнивает значения.
Object t = 4;
Object s = 4;
if (t == s) { // false
}
List<Object> q = new List<object>() { t };
Boolean found = q.Contains(s); // found = true!
В приведенном выше коде я не удивлен t == s
возвращением false
; он сравнивает ссылки на два объекта, а ссылки не совпадают.
Но я удивляюсь, что Содержит возвращается верно; очевидно, это не просто сравнение ссылок на объекты.. это как сравнение необоснованных значений 4 и 4.. но как и почему он знает, чтобы удалить объекты для их сравнения? Я пытаюсь понять, чем больше приключений здесь играет.
Выражение
q.Contains(s)
ищет элемент q
, для которого EqualityComparer<object>.Default
.Equals(element, s)
истинно. Для примитивов в штучной упаковке это сравнивает значения.
Contains
, внутренне, использует метод экземпляра object.Equals
для сравнения элементов. Он не использует оператор ==
.
Метод Equals
является виртуальным, тогда как == operator
является статическим. Это означает, что оператор ==
определит, какой код будет выполняться на основе типа времени компиляции переменной (а не объекта во время выполнения переменной). С другой стороны, виртуальный метод не статически связан. Он определяет, какая перегрузка Equals
должна выполняться в зависимости от типа времени выполнения переменной.
В соответствии с документацией Contains
:
Определяет, содержит ли последовательность указанный элемент, используя сопоставитель равенства по умолчанию.
Contains
использует Equals
методы вместо оператора ==
.
==
использует тип переменных для определения того, какое равенство сравнивается.
Для object
/object
он выполнит ссылочное равенство.
Contains
будет использовать метод Equals
, который является виртуальным и может быть перегружен для сравнения значений. В этом случае int
записывается как таковой.
Contains
использует object.Equals(object)
, который для int
реализован так, что 4.equals(4)
является истинным. ==
с объектами с каждой стороны использует только сравнительное сравнение.
Также обратите внимание: object.Equals(t, s) == true
потому что этот метод использует метод экземпляра Equals
, если ссылочное равенство терпит неудачу.