在.net中有幾種比較相等的方法
object的靜態ReferenceEquals()
object的靜態Equals()
object的範例Equals()
運算符==
object的範例Equals()運算符==和用法。 ReferenceEqualsReferenceEquals用於比較引用類型的參考是是否指向同一個物件。它只能比較引用型別。當把值類型傳給它的時候永遠都會返回false,因為值類型作為參數的時候首先會裝箱,經過裝箱的值類型哪怕是指相等,但是也是兩個不同的對象,所以變量是指向不同的對象,所以永遠回傳false。
int x = 10;
int y = 10;
bool b1 = object.ReferenceEquals(x,y);
public class Person
{
public int PersonId
{
} { return _person }com
private string _firstName;
public string FirstName
{get { return _firstName; }
set { _firstName = value; }
}
private string _last; }
set { _lastName = value ; }
}
public Person() { }
{
this._personId = personId; }}
呼叫程式碼
Person person1 = new Person(1,"Edrick","Liu");
Person person2 = new Person(2, "Meci", "Luo");
Person person3 = person; bool br1= object.ReferenceEquals(person1,person2);
bool br2 = object.ReferenceEquals(person2, person3);
我們可以發現第一個回傳false,第二個回傳true。那麼如果其中有一個物件為null,或是兩個物件都為null呢?結果會為false,如果兩個都為null呢?結果為true。他們不會引發異常。
實例Equals
實例Equals算是比較複雜的比較方法。實例Equals可以比較引用是否指向同一個對象,同時可以依值來比較對象。如果要按值比較對象,我們就需要重載Equals對象來實現我們的比較邏輯。同時Equals預設也支援比較值類型的相等。那我們該怎麼重載Equals來讓物件具有值相等性的比較呢?
MSDN給我們列出了一些準則
{
private int _personId;public int PersonId{
} { return @person }comprivate string _firstName ;
public string FirstName
get { return _firstName; }
set { _firstName = value; }
}
private string _last; }
set { _lastName = value; }
}
public Person() { }
{
this._personId = personson;}
public override bool Equals(object obj)
{
if (obj != null && obj is Person)
Person p = obj obj is Person)
{Person p = obj obj is Person)
{
Person p = obj as Person; == p.FirstName) && (LastName == p.LastName);
}
else
{
}
}
public override int GetHashCode()
{
}
}
呼叫程式碼
Person person2 = new Person(2, "Meci", "Luo");
Person person2 = new Person(2, "Meci", "Luo");
2 person3 = person;
Person person4 = new Person(1, "Edrick", "Liu");
Console.WriteLine(person4.Equals(person1));
Console.WriteLine(person4.Equals(person2));結果,第一個為true,第二個為false。重載的時候不能出現異常。那如果有一個類別繼承Person呢,我們又改如何比較衍生類別。
公共班級學生:人
{
private int _studentNumber;
public int StudentNumber
{
get { return _studentNumber;
set {
get { return _studentNumber;
.
public Student( int personId, string firstName, string lastName, int StudentNumber){
this.PersonId = personId;
this.名字= 名字;
this.LastName = 姓氏;
this._studenŎ NpN; Equals(object obj)
{
if (obj != null && obj is Person)
Student s = obj as Student;
return base.Equals(obj)&&StudentNumber==s.StudentNumber;
}
否則
{
回傳false;
}
}
public override int GetHashCode()
{
return base.GetHashCode()^StudentNumber;
Student s2 = new Student(2, "Meci", "Luo", 2);
Student s3 = new Student(1, "Edrick", "Liu", 1);
Console. WriteLine(s1.Equals(s2));
Console.WriteLine(s1.Equals(s3));
我們只需要呼叫父類別的Equals方法和衍生類別中的比較的新值。
靜態Equals
這個方法當然比較有趣的一個方法了。這個方法也是靜態的,能比較引用,能比較值型別。如果比較的型別重載了實例的Equals,那麼它也能也能比較物件的值。所以它回傳true有不同的情況。
1,引用指向同一物件
2,比較兩個null
3 ,重載了Equals的實例方法回傳true
Student s1 = new Student(1, "Edrick", "Liu", 1) ;
Student s2 = new Student(2, "Meci", "Luo", 2);學生s3 = 新學生(1, "Edrick", "Liu", 1);
學生s4 = s3;Console .WriteLine(object.Equals(s1,s3));Console.WriteLine(object.Equals(s4, s3));
這兩個都是true,這裡靜態的Equals跟靜態的EqualsReference有個區別,靜態的靜態的Equals如果有一個參數為null會觸發異常。
有趣下面討論一個的現象,如果重載了Equals但是沒有重載==行為,會發生什麼
Student s1 = new Student(1, "Edrick", "Liu", 1);
學生s3 = 新生(1, "Edrick", "Liu", 1);
學生s4 = s3;
Console.WriteLine(s3==s4);
第一個為假,第二個為真。這顯然不符合我們的意思,所以重載了等於必須重載==,同樣重載了==也必須重載等於。這樣符合我們的意思,也能確保在使用集合的時候,程式碼能遵循我們的意思運作。因為集合coll[0]==co[0]其實比較的是引用,但是如果我們的Equals比較的是物件的值那麼最後程式碼還是不能按照我的期望的運行。
==運算子
==號運算子其實跟實例的Equals沒有太大區別,==是運算符,而Equals是方法。它們都重寫。預設等於比較引用和比較值。關於==的重載可以參考運算子一文中的運算子重載。
總結它們的區別:
ReferenceEquals:靜態方法,不能重寫,只能比較引用,如果有參數為null返回會false,不會觸發異常,如果比較值類型,則始終傳回false。
Equals:實例方法,預設可以比較引用也可以比較值,重寫。按值比較物件。
靜態Equals:靜態方法,不能重寫。如果沒有重寫Equals,比較引用,或比較值。如果重載了Equals方法。比較引用,或者比較值,或按重寫的Equals比較,如果其中一個參數為null ,發送異常
==運算符:可以按引用比較,也可以按值比較。可以重寫。是操作運算符。
最後需要的是,如果重載了Equals,則最好是重載GetHashCode,必須重載==運算子。
更多Equals,ReferenceEquals,==的區別相關文章請關注PHP中文網!