I've come across this question quite a few times, and while the answers make sense, i wanted to check it out myself with a simple console app.
class Program
{
static void Main(string[] args)
{
// Case 1 : FOR REFERENCE TYPES where class b is a copy of class a
Class1 a = new Class1("Hello");
Class1 b = a;
Console.WriteLine("case 1");
Console.WriteLine(a.GetHashCode());
Console.WriteLine(b.GetHashCode());
Console.WriteLine(a==b); //true
Console.WriteLine(a.Equals(b)); //true
// Case 2 : FOR REFERENCE TYPES where class b is not a copy of class a, but it assigned the same values
// Though the referenced memory addresses are different, the fields of the class are assigned the same values, but will have different hashcodes and are therfore not equal.
Class1 c = new Class1("Hello");
Console.WriteLine(" ");
Console.WriteLine("case 2");
Console.WriteLine(a.GetHashCode());
Console.WriteLine(c.GetHashCode());
Console.WriteLine(a==c);//false
Console.WriteLine(a.Equals(c));//false
// Case 3 : FOR REFERENCE TYPES where two strings are assigned the same values, an exception to the way value types behave.
// using the '==' operstor with strings compares their values not memory addresses.
string s1 = "hi";
string s2 = "hi";
Console.WriteLine(" ");
Console.WriteLine("case 3");
Console.WriteLine(s1 == s2);//true
Console.WriteLine(s1.Equals(s2));//true
//Case 4 : FOR VALUE TYPES - they are the same when comparing the same type.
int x = 5;
int y = 5;
Console.WriteLine(" ");
Console.WriteLine("case 4");
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(x == y);//true
Console.WriteLine(x.Equals(y));//true
// Case 5 : Another value type scenario for completeness
x = y;
Console.WriteLine(" ");
Console.WriteLine("case 5");
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(x.GetType());
Console.WriteLine(y.GetType());
Console.WriteLine(x == y);//true
Console.WriteLine(x.Equals(y));//true
// Case 6 : Yet Another value type scenario for completeness, with different value types.
float z = 5;
Console.WriteLine(" ");
Console.WriteLine("case 6");
Console.WriteLine(x.GetType());
Console.WriteLine(z.GetType());
Console.WriteLine(x);
Console.WriteLine(z);
Console.WriteLine(x == z);//true
Console.WriteLine(x.Equals(z));//false, as the values being compared are of two different types- int and float. The .Equals method expects them to be the same type.
// Case 7 : For giggles, Yet Another ref type scenario for completeness, with objects.
string s3 = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
string s4 = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
object obj1 = s3;
object obj2 = s4;
Console.WriteLine(" ");
Console.WriteLine("case 7");
Console.WriteLine(obj1.ToString());
Console.WriteLine(obj2.ToString());
Console.WriteLine(obj1.GetHashCode());
Console.WriteLine(obj2.GetHashCode());
Console.WriteLine(obj1 == obj2);//false - as they refer to different addresses.
Console.WriteLine(obj1.Equals(obj2));//true - in this case both objects have the same hashcode.
Console.ReadKey();
}
public class Class1
{
string name;
public Class1(string strName)
{
name = strName;
}
}
}
Assumption 1 : What i understood from the commonly posted replies was that for reference types, a==b compares references , whereas a.Equals(b) compares the actual values referenced. This is what threw me off when viewing the results of my program.
With reference to my program, In Case 2 - Though the referenced memory addresses for a and c are different, their fields are assigned the same values. Still a.Equals(c) returns false as they still are not equal as they have different hashcodes. I had assumed they would return true initially based on Assumption 1, but it makes sense they are not equal. But then what really is the exact difference between == and .Equals?
In case 3 , using the '==' operator with strings compares their values not memory addresses.
In case 6, the value types being compared by the .Equals method are different, whereas the method expects them to be of the same type. Hence it returns false.
What I still don't understand is case 7. Why do the objects have the same hashcode in this case? Sorry for the lengthy code and thanks in advance!