Object.Equals Method (System)

Switch View :
ScriptFree
.NET Framework Class Library
Object.Equals Method

Determines whether two Object instances are equal.

This member is overloaded. For complete information about this member, including syntax, usage, and examples, click a name in the overload list.

Overload List

  Name Description
Public method Supported by the .NET Compact Framework Supported by the XNA Framework Equals(Object) Determines whether the specified Object is equal to the current Object.
Public method Static member Supported by the .NET Compact Framework Supported by the XNA Framework Equals(Object, Object) Determines whether the specified Object instances are considered equal.
Top
See Also

Reference

Community Content

R Petrusha - MSFT
I think this page mis-/under-documents object.Equals( a, b )
I'm entirely new to C# and .NET (but a long-time c/c++ developer), I was lead to this page in trying to answer a question in reading through my first C# book. I haven't seen what I believe is the correct answer clarified here yet, so I'll add my $0.02. The static function object.Equals( a, b ) appears to behave like it was written like the following (you can confirm this with a test using your own class for "a" and see that a.Equals is called, so there is no magic member by member memory comparison going on). This explains why classes which override Equals with a member by member comparison return true from object.Equals( a, b ) when a and b are not the same reference. object.Equals(a, b) returns false if "a" doesn't implement it's own Equals() (and a and are not equal references)

public static bool Equals( object a, object b )

{

if ( object.ReferenceEquals( a, b ) )

return true;

return a.Equals( b );

}





R Petrusha - MSFT
Correct Explanation

The Object.Equals method tests whether the CONTENT of two objects are the same irrespective of whether the two objects are referring to the same memory location on the heap or not

Hence the below code snippet:

StringBuilder foo = new StringBuilder();
foo.Append("lol");
StringBuilder bar= new StringBuilder();
bar.Append("lol");

foo.Equals(bar)


will always return true since both foo and bar have the CONTENT as "lol"


However the following will return false:

Object.ReferenceEquals(foo,bar)


since foo and bar are two SEPARATE objects on the heap and hence their memory references are not the same.

The exception to the above is in case of strings.

Consider the following code snippet:

  
string s1 = "Hello";
string s2 = "Hello"; 
Console.WriteLine(s1.Equals(s2)); // this returns true since both s1 and s2 contain the string 'Hello' 
Console.WriteLine(Object.ReferenceEquals(s1, s2)); // this also returns true!!


Here the Object.ReferenceEquals returns true since although s1 and s2 are two different string objects; .NET CLR handles string in a special way and according to my understanding uses string pooling wherein two strings that have the same content will point to the same memory location.

Let me know if there is any misunderstanding on my side with respect to the above statement.

Object.Equals, Object.ReferenceEquals and Equality


Both statements are only partially correct.

First, Object.Equals does not always test for value equality; it tests for value equality for value types, and reference equality for reference types. Nor is it correct to assume that a call to the Equals method is resolved as a call to Object.Equals. For example, the first code fragment above uses two StringBuilder objects (StringBuilder is a reference type) to show that Object.Equals tests for value equality. However, StringBuilder overrides the Equals method to test for value equality. What is actually called here is StringBuilder.Equals, not Object.Equals.

The following example illustrates calls to Object.Equals that test for reference equality. In this example, person1a and person1b reference the same Person object, and so calls to the Object.Equals method indicates that they are equal. person1a and person2, on the other hand, have the same value, but Object.Equals returns false because they do not reference a single Person object.

using System;
public class Person
{
private string personName;

public Person(string name)
{
this.personName = name;
}

public override string ToString()
{
return this.personName;
}
}
public class Example
{
public static void Main()
{
Person person1a = new Person("John");
Person person1b = person1a;
Person person2 = new Person("John");

Console.WriteLine("Calling Equals:");
Console.WriteLine(person1a.Equals(person1b)); // Displays True.
Console.WriteLine(person1a.Equals(person2)); // Displays False.

Console.WriteLine("\nCasting to an Object:");
Console.WriteLine(((object) person1a).Equals((object) person1b)); // Displays True.
Console.WriteLine(((object) person1a).Equals((object) person2)); // Displays False.
}
}


However, if we change Person from a reference type (a class) to a value type (a structure), Object.Equals now tests for value equality.

using System;



public struct Person
{
private string personName;

public Person(string name)
{
this.personName = name;
}

public override string ToString()
{
return this.personName;
}
}

public class Example
{
public static void Main()
{
Person person1a = new Person("John");
Person person1b = person1a;
Person person2 = new Person("John");

Console.WriteLine("Calling Equals:");
Console.WriteLine(person1a.Equals(person1b)); // Displays True.
Console.WriteLine(person1a.Equals(person2)); // Displays True.

Console.WriteLine("\nCasting to an Object:");
Console.WriteLine(((object) person1a).Equals((object) person1b)); // Displays True.
Console.WriteLine(((object) person1a).Equals((object) person2)); // Displays True.
}
}


Second, when Object.ReferenceEquals returns True when evaluating two string objects, it does so because they share a common reference, not because their values are equal. The .NET Framework interns string literals. In the case of the third brief code fragment above, "Hello" is the interned string, and both s1 and s2 are references to the single interned string. However, as the following example shows, this is very different from a test for value equality. In this example, s1 and s2 reference the same object, since they are instantiated from the same string literal. On the other hand, the values of s3 and s4 are not derived from interned strings; instead, their values are built by iterating a character array. As a result, Object.ReferenceEquals returns False when passed s1 and s3 as well as s3 and s4.

using System;
using System.Text;

public class Example
{
public static void Main()
{
string s1 = "A string";
string s2 = "A string";

Console.WriteLine(Object.ReferenceEquals(s1, s2)); // Displays True.
Console.WriteLine("Interned: {0}",
String.IsInterned(s1) != null ? "True" : "False" ); // Displays Interned: True.



char[] chars = { 'A', ' ', 's', 't', 'r', 'i', 'n', 'g' };
StringBuilder sb = new StringBuilder();
foreach (var ch in chars)
sb.Append(ch);
string s3 = sb.ToString();
string s4 = sb.ToString();

Console.WriteLine(Object.ReferenceEquals(s1, s3)); // Displays False.
Console.WriteLine(Object.ReferenceEquals(s3, s4)); // Displays False.
}
}


I hope that this helps to clarify some of the confusion surrounding tests for equality with the System.Object class.

--Ron Petrusha
Common Language Runtime User Education
Microsoft Corporation


R Petrusha - MSFT
More Clarity

check this article . says opposite

http://msdn.microsoft.com/en-us/library/ms173147(VS.80).aspx

It says a==b is for Reference equal and a.equals(b) is for Value equal

Object.Equals and Value Equality


It is worth noting that while a==b tests for reference equality, a.Equals(b) can test for either reference equality or value equality, depending on the type of a. If a is a reference type, Equals tests for reference equality. If a is a value type, Equals tests for value equality. The referenced topic did not say that Equals is for value equality. It said that Object.Equals can be overridden to test for value equality. Because reference equality means that two variables refer to the same object, there is no need to ever override Object.Equals to test for reference equality. This is not the case, however, with value equality. Does equality mean that public fields/properties are equal, or that any private fields must be equal as well? If a value type represents a numeric value that can have trailing fractional zeros, are the zeros ignored when testing for equality? In any case, while reference equality has a single definition, the definition of value equality depends on the type to be compared for equality.


--Ron Petrusha
Developer Division User Education
Microsoft Corporation


R Petrusha - MSFT
I'm Confused here. The MS Documentation states differently

MS doc says Equals tests reference equality is this a misprint?
It's obvious that Equals test DOES test content.

"The default implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object."

Object.Equals, Reference Equality, and Value Equality

This is not a misprint. The documentation is correct in stating that Object.Equals tests reference equality for reference types. For value types, it tests for value equality.

The use of the term "bitwise equality" in the documentation is unfortunate, since it is at best ambiguous. For example, a bitwise comparison of a signed integer whose value is -1 (or 0xFF) and an unsigned integer whose value is 255 (or 0xFF) should return true, since each bit of the two values is the same.

So at a minimum, the two sentences quoted above should be revised to read, "The implementation of the Equals method by the Object class supports reference equality for reference types, and value equality for value types. Reference equality means the object references that are compared refer to the same object. Value equality means that the two objects that are compared have the same values." More generally, we are currently in the process of revising the documentation for Object.Equals so that it will be clearer and less confusing. The revisions should appear in the online version of the documentation in the near future.

--Ron Petrusha
Developer Division User Education
Microsoft Corporation


Dan Solovay
Equals is intended to be overridden

The Equals method for the Object class is equivalent to ReferenceEquals. However, because it is an instance method, it can be overridden by class designers to test if content is equal (as is done in the string class). The test for reference equality is a fallback implementation.

The MSDN article on the Object class states:

"Because all classes in the .NET Framework are derived from Object, every method defined in the Object class is available in all objects in the system. Derived classes can and do override some of these methods, including:
Equals - Supports comparisons between objects. ..."


Thomas Lee
It behaves different for custom objects and immutable objects
By default, the operator == tests for reference equality. This is done by determining if two references indicate the same object. Therefore reference types do not need to implement operator == in order to gain this functionality.

When a type is immutable, meaning the data contained in the instance cannot be changed, overloading operator == to compare value equality instead of reference equality can be useful because, as immutable objects, they can be considered the same as long as they have the same value. Overriding operator == in non-immutable types is not recommended.

Also, overloaded operator == implementations should not throw exceptions. Any type that overloads operator == should also overload operator !=. For

Thomas Lee
The content above ("This tests instance equality") is incorrect
It confuses Object.Equals( ) with Object.ReferenceEquals( )

AL202
some more found on ==
some more i found on msdn site

For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types other than string, == returns true if its two operands refer to the same object. For the string type, == compares the values of the strings.

rac1234
Default versus overridden implementations
In response to the post by Equals, above:

No, I don't think it's a misprint. As I understand it, Microsoft are saying that the default implementation of Equals checks for reference equality, but in your own objects you may prefer to override this method to test for value equality (sameness of content). In other words, don't use the default implementation of Equals on your own objects where you are interested in whether the objects have the same value rather than whether they are the same instance. The default implementation will not give you the right answer in that case.

If you override Equals to check for value equality, you can still check for reference equality on your objects by using the ReferenceEquals method.

Another implication of this is that you should not depend on the Equals method to check for reference equality - use ReferenceEquals instead since Equals may have been overridden to test value equality.



lambertwm
This tests instance equality
-- IMHO this is incorrect, lambertwm --

if

object foo = new object();
object bar = foo;

then

object.Equals(foo, bar)

evaluates to true. Variables foo and bar both point to the same object on the managed heap. If we were to say

StringBuilder foo = new StringBuilder();
foo.Append("lol");
StringBuilder bar= new StringBuilder();
bar.Append("lol");

and then examine the memory locations for foo and bar, they would be indistinguishable. The only difference between the two is that they are seperate objects on the managed heap. In this case, even though we would consider them to be the same, as they have the exact same content,

object.Equals(foo, bar)

would evaluate to false because they are two different objects.

It is the responsibility of coders to override the operators == and != and to provide overrides for both Equals methods if you want to change this behavior so that you compare the states of two objects rather than the instances of the objects when testing for equality.