Michael Ray Lovett
Michael Ray Lovett

Reputation: 7060

Why does Contains compare objects differently than ==?

Object t = 4;
Object s = 4;

if (t == s) {       // false
}

List<Object> q = new List<object>() { t };
Boolean found = q.Contains(s);          // found = true!

In the above code, I am not surprised by t == s returning false; it's comparing references to two objects and the references aren't the same.

But I am surprised the the Contains is returning true; obviously it's not just comparing object references..it's like it's comparing the unboxed values of 4 and 4..but how and why does it know to unbox the objects to compare them? I'm trying to understand the bigger pricniple at play here.

Upvotes: 14

Views: 1153

Answers (6)

Guvante
Guvante

Reputation: 19213

== uses the type of the variables to determine what equality to compare.

For object/object it will do a reference equality.

Contains will use the Equals method which is virtual and may be overloaded to do a value compare. In this case int is written as such.

Upvotes: 0

Servy
Servy

Reputation: 203844

Contains, internally, is using the instance object.Equals method to compare the elements. It is not using the == operator.

The Equals method is virtual, whereas the == operator is static. This means that the == operator will determine which code to run based on the compile time type of the variable (and not the object at run time that the variable holds). A virtual method, on the other hand, is not statically bound. It determines which overload of Equals to run based on the run time type of the value the variable.

Upvotes: 7

Sam Harwell
Sam Harwell

Reputation: 99959

The expression

q.Contains(s)

is looking for an element of q for which EqualityComparer<object>.Default.Equals(element, s) is true. For boxed primitives, this compares the values.

Upvotes: 13

Tim S.
Tim S.

Reputation: 56556

Contains uses object.Equals(object), which for ints are implemented so that 4.equals(4) is true. == with objects on each side uses reference comparison only.

Also of note: object.Equals(t, s) == true because this method uses the instance's Equals method if reference equality fails.

Upvotes: -1

MarcinJuraszek
MarcinJuraszek

Reputation: 125650

Contains uses Equals methods instead of == operator.

Upvotes: 2

Adriano Carneiro
Adriano Carneiro

Reputation: 58615

According to the Contains documentation:

Determines whether a sequence contains a specified element by using the default equality comparer.

Upvotes: 5

Related Questions