在以下的演示樣例中。由于它們是一個暫存的字符串的兩個實例,s1 和 s2 相等。 可是,s3 和 s4 不相等,由于雖然它們是具有同樣的字符串值。字符串不會暫留。
1.1.3 使用ReferenceEquals()比較兩個對象 object o = null; object p = null; object q = new Object(); bool B4 = Object.ReferenceEquals(o, p);//true p = q; bool B5 = Object.ReferenceEquals(p, q);//true bool B6 = Object.ReferenceEquals(o, p);//false 1.2 Equals()方法 1.2.1 虛擬的Equals()方法 命名空間: System 程序集:mscorlib(在mscorlib.dll中) 語法:public virtual bool Equals(Object obj) ? ? Equals()虛擬版本號的System.Object實現代碼也比較引用。但由于這種方法是虛擬的。所以能夠在自己的類中重寫它。按值來比較對象。
特別是假設希望類的實例用作字典中的鍵,就須要重寫這種方法,以比較值。否則。依據重寫Object.GetHashCode()的方式。包括對象的字典類要么不工作,要么工作的效率很低。在重寫Equals()方法時要注意,重寫的代碼不會拋出異常。這是由于假設拋出異常。字典類就會出問題,一些在內部調用這種方法的.NET基類也可能出問題。
? ? Equals 是一個虛方法。同意不論什么類重寫事實上現。表示某個值(本質上能夠是不論什么值類型)或一組值(如復數類)的不論什么類都應該重寫 Equals。假設類型要實現 IComparable,則它應該重寫 Equals。
Equals 的新實現應該遵循 Equals 的全部保證: x.Equals(x) 返回 true。 x.Equals(y) 與 y.Equals(x) 返回同樣的值。 假設 (x.Equals(y) && y.Equals(z)) 返回 true,則 x.Equals(z) 返回 true。 僅僅要不改動 x 和 y 所引用的對象,x.Equals(y) 的興許調用就返回同樣的值。 x.Equals(null) 返回 false。 ? ? Equals 的新實現不應該引發異常。建議重寫 Equals 的不論什么類同一時候也重寫 System.Object.GetHashCode。除了實現 Equals(對象)外。還建議全部的類為自己的類型實現 Equals(類型)以增強性能。
比如:
class TwoDPoint : System.Object { public readonly int x, y; public TwoDPoint(int x, int y) //constructor { this.x = x; this.y = y; } public override bool Equals(System.Object obj) { // If parameter is null return false. if (obj == null) { return false; } // If parameter cannot be cast to Point return false. TwoDPoint p = obj as TwoDPoint; if ((System.Object)p == null) { return false; } // Return true if the fields match: return (x == p.x) && (y == p.y); } public bool Equals(TwoDPoint p) { // If parameter is null return false: if ((object)p == null) { return false; } // Return true if the fields match: return (x == p.x) && (y == p.y); } public override int GetHashCode() { return x ^ y; } } 1.2.2 靜態的Equals()方法 命名空間: System 程序集:mscorlib(在mscorlib.dll中) 語法:public static bool Equals(Object objA, Object objB) Dog m1 = new Dog("Alaskan Malamute"); Dog m2 = new Dog("Alaskan Malamute"); Dog g1 = new Dog("Great Pyrenees"); Dog g2 = g1; Dog d1 = new Dog("Dalmation"); Dog n1 = null; Dog n2 = null; Console.WriteLine("null = null: {0}", Object.Equals(n1, n2));//true Console.WriteLine("null Reference Equals null: {0}\n", Object.ReferenceEquals(n1, n2));//true Console.WriteLine("{0} = {1}: {2}", g1, g2, Object.Equals(g1, g2));//true Console.WriteLine("{0} Reference Equals {1}: {2}\n", g1, g2, Object.ReferenceEquals(g1, g2));//true Console.WriteLine("{0} = {1}: {2}", m1, m2, Object.Equals(m1, m2));//true Console.WriteLine("{0} Reference Equals {1}: {2}\n", m1, m2, Object.ReferenceEquals(m1, m2));//falseConsole.WriteLine("{0} = {1}: {2}", m1, d1, Object.Equals(m1, d1)); //false Console.WriteLine("{0} Reference Equals {1}: {2}", m1, d1, Object.ReferenceEquals(m1, d1)); //false?
? ? 靜態 Equals(Object, Object) 方法指示兩個對象。objA 和 objB,是否相等
? ? 它確定兩個對象是否表示同一對象引用。 假設成功,該方法返回 true. 這測試與調用 ReferenceEquals 方法等效。 另外。假設 objA 和 objB 都為 null,則方法返回 true。 它確定 objA 或 objB 是否 null。 假設是這樣。則返回 false。 ? ? 假設兩個對象不表示同一對象引用,且均不為 null,它調用 objA。Equals(objB) 而且返回結果。
這意味著。假設 objA 重寫 Object.Equals(Object) 方法,該重寫調用。
1.3 比較運算符(==) ? ? 對于引用類型,== 默認的行為與ReferenceEquals的行為同樣,僅有兩個對象指向同一個Reference的時候才返回true。可是.NET Framework中的類非常多對==進行了重載,比如String類的==與Equals的行為同樣。推斷兩個字符串的內容是否相等。所以在應用中。對于 系統定義的引用類型建議不要使用==操作符,以免程序出現與預期不同的執行結果。 重載的運算符 == 實現不應引發異常。重載運算符 == 的不論什么類型還應重載運算符 !=。比如:
public static bool operator ==(ThreeDPoint a, ThreeDPoint b) { // If both are null, or both are same instance, return true. if (System.Object.ReferenceEquals(a, b)) { return true; } // If one is null, but not both, return false. if (((object)a == null) || ((object)b == null)) { return false; } // Return true if the fields match: return a.x == b.x && a.y == b.y && a.z == b.z; } public static bool operator !=(ThreeDPoint a, ThreeDPoint b) { return !(a == b); } 2.比較值類型的相等性 ? ? 在比較值類型的相等時,採用與引用類型同樣的規則:ReferenceEquals()用于比較引用,Equals()用于比較值,比較運算發能夠看做是一個中間項。但最大的差別是值類型須要裝箱。才干把他們轉換為引用。 ReferenceEquals()在應用于值類型時。總是返回false。由于調用這種方法,須要裝箱。