私はこの質問に何度も出くわしました.答えは理にかなっていますが、単純なコンソールアプリで自分でチェックしたいと思いました.
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;
}
}
}
仮定1:一般的に投稿された返信から私が理解したのは、参照型の場合、 a==b は参照を比較し、 a.Equals(b) は参照される実際の値を比較するということでした。これは、私のプログラムの結果を表示するときに私を失望させたものです.
私のプログラムを参照すると、ケース2の場合-aとcの参照メモリアドレスは異なりますが、それらのフィールドには同じ値が割り当てられます。それでも a.Equals(c) は false を返します。ハッシュコードが異なるため、まだ等しくないからです。仮定 1 に基づいて最初は true を返すと想定していましたが、それらが等しくないことは理にかなっています。しかし、実際には == と .Equals の正確な違いは何でしょうか?
ケース 3 では、'==' 演算子を文字列で使用すると、メモリ アドレスではなく値が比較されます。
ケース 6 では、.Equals メソッドによって比較される値の型が異なりますが、メソッドはそれらが同じ型であると想定しています。したがって、false を返します。
私がまだ理解していないのは、ケース 7 です。この場合、オブジェクトのハッシュコードが同じなのはなぜですか? 長いコードで申し訳ありませんが、事前に感謝します!