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.
| Name | Description | |
|---|---|---|
|
Equals(Object) | Determines whether the specified Object is equal to the current Object. |
|
Equals(Object, Object) | Determines whether the specified Object instances are considered equal. |
Reference
public static bool Equals( object a, object b )
{
if ( object.ReferenceEquals( a, b ) )
return true;
return a.Equals( b );
}
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
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
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
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. ..."
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
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.
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.
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.