Heim >Backend-Entwicklung >C#.Net-Tutorial >Der Unterschied zwischen Equals, ReferenceEquals,==

Der Unterschied zwischen Equals, ReferenceEquals,==

高洛峰
高洛峰Original
2016-12-16 09:53:011079Durchsuche

Es gibt mehrere Methoden zum Vergleichen der Gleichheit in .net

Statische ReferenzEquals() des Objekts

Statische Equals() des Objekts

Beispiel für objectEquals()

Operator==

Im Folgenden werden ihre Unterschiede und ihre Verwendung vorgestellt.

ReferenceEquals

ReferenceEquals wird verwendet, um zu vergleichen, ob Referenzen von Referenztypen auf dasselbe Objekt verweisen. Es können nur Referenztypen verglichen werden. Wenn ein Werttyp an ihn übergeben wird, wird immer „false“ zurückgegeben, da der Werttyp bei Verwendung als Parameter zuerst eingerahmt wird. Auch wenn sich der eingerahmte Werttyp auf Gleichheit bezieht, handelt es sich immer noch um zwei verschiedene Objekte, sodass die Variable darauf zeigt Es handelt sich um ein anderes Objekt, daher wird immer „false“ zurückgegeben.

int x = 10;
int y = 10;
bool b1 = object.ReferenceEquals(x,y);
Das Ergebnis wird hier definitiv false zurückgeben, aber wenn es sich um einen Vergleich handelt Referenztypen, wahr, wenn die beiden Referenzen auf dasselbe Objekt verweisen.

Wir definieren immer noch zuerst die Entitätsklasse

öffentliche Klasse Person
{
private int _personId;

öffentliche int PersonId
{
get { return _personId; }
set { _personId = value; }

private string _firstName;

public string FirstName

{
get { return _firstName; }
set { _firstName = value; }
>

private string _lastName;

public string LastName

{
get { return _lastName; }
set { _lastName = value; }
}

public Person() { }

public Person(int personId, string firstName, string lastName)

{
this. _personId = personId;
this._firstName = firstName;
this._lastName = lastName;
}
}
Anrufcode

Person person1 = neue Person(1," Edrick ","Liu");

Person person2 = new Person(2, "Meci", "Luo");
Person person3 = person2;
bool br1= object.ReferenceEquals(person1,person2) ;
bool br2 = object.ReferenceEquals(person2, person3); Wir können feststellen, dass das erste false und das zweite true zurückgibt. Was ist also, wenn eines der Objekte null ist oder beide Objekte null sind? Das Ergebnis ist falsch. Was ist, wenn beide null sind? Das Ergebnis stimmt. Sie lösen keine Ausnahmen aus.

Instance Equals

Instance Equals ist eine relativ komplexe Vergleichsmethode. Instanzen von Equals können vergleichen, ob Referenzen auf dasselbe Objekt verweisen, und Objekte nach Wert vergleichen. Wenn wir Objekte nach Wert vergleichen möchten, müssen wir das Equals-Objekt überladen, um unsere Vergleichslogik zu implementieren. Gleichzeitig unterstützt Equals standardmäßig auch die Gleichheit von Vergleichswerttypen. Wie überladen wir also Equals, um Objekten Wertgleichheitsvergleiche zu ermöglichen?

MSDN listet einige Richtlinien für uns auf

Mit Ausnahme von Fällen mit Gleitkommatypen gibt x.Equals(x) „true“ zurück.

x.Equals(y) gibt den gleichen Wert zurück wie y.Equals(x).

x.Equals(y) gibt true zurück, wenn sowohl x als auch y NaN sind.

(x.Equals(y) && y.Equals(z)) gibt genau dann true zurück, wenn x.Equals(z) true zurückgibt.

Aufeinanderfolgende Aufrufe von x.Equals(y) geben denselben Wert zurück, solange die durch x und y referenzierten Objekte nicht geändert werden.

x.Equals(nullNothingnullptrnull reference (Nothing in Visual Basic)) gibt false zurück.

Werfen wir einen Blick auf den neu geschriebenen Code

public class Person

{

private int _personId;

public int PersonId

{

get { return _personId; }
set { _personId = value; }

private string _firstName;

public string FirstName

{

get { return _firstName ; }

set { _firstName = value; }

private string _lastName;

public string LastName

{

get { return _lastName }

set { _lastName = value; }

}

public Person() { }

public Person(int personId, string firstName, string lastName)

{

this . _personId = personId;

this._firstName = firstName;


public override bool Equals(obj)
if ( obj != null && obj ist Person)
{
Person p = obj als Person;

return (PersonId == p.PersonId) && (FirstName == p.FirstName) && (LastName = = p.LastName);

}
else
{
return false;}
}

public override int GetHashCode()
{
return base.GetHashCode()^PersonId;
}
}
Aufrufcode

Person person1 = neue Person(1,"Edrick","Liu"); Person person2 = neue Person(2, „Meci“, „Luo“);

Person person3 = person2;
Person person4 = neue Person(1, „Edrick“, „Liu“);

Console.WriteLine(person4.Equals(person1));
Console.WriteLine(person4.Equals(person2));
Wir können die Ergebnisse sehen, das erste ist wahr und das zweite ist falsch. Beim Nachladen sollten keine Ausnahmen auftreten. Wenn es also eine Klasse gibt, die Person erbt, wie vergleichen wir dann abgeleitete Klassen?

public class Student:Person 

private int _studentNumber;

public int StudentNumber 

get { return _studentNumber; } 
set { _studentNumber = value; } 
}

public Student() { }

public Student(int personId, string firstName, string lastName, int studentNumber) 

this.PersonId = personId ; 
this.FirstName = firstName; 
this.LastName = lastName; 
this._studentNumber = studentNumber; 
}

public override bool Equals(object obj) 

if (obj != null && obj is Person) 

Student s = obj as Student; 
return base.Equals(obj)&&StudentNumber==s.StudentNumber; 

else 

return false; 

}

public override int GetHashCode() 

return base.GetHashCode()^StudentNumber; 


调用代码

Student s1 = neuer Student(1, „Edrick“, „Liu“, 1); 
Student s2 = neuer Student(2, „Meci“, „Luo“, 2); 
Student s3 = neuer Student(1, "Edrick", "Liu", 1);

Console.WriteLine(s1.Equals(s2)); 
Console.WriteLine(s1.Equals(s3)); 
我们只需要调用父类的Equals方法和比较派生类中的新值.

静态Equals

这个方法算是比较有趣的一个方法了.这个方法也是静态的它能比较引用,能比较值类型.如果比较的类型重载了实例的Equals,那么它也能也比较对象的值.所以它返回true有三种情况.

1,引用指向的实例方法返回true

Student s1 = neuer Student(1, „Edrick“, „Liu“, 1); 

Student s2 = neuer Student(2, „Meci“, „Luo“, 2); 

Student s3 = neuer Student(1, „Edrick“, „Liu“, 1); 

Student s4 = s3;


Console.WriteLine(object.Equals(s1,s3)); 
Console.WriteLine(object.Equals(s4, s3)); 
这两个都为true,这里静态的Equals跟静态的EqualsReference有一个区别,静态的Equals如果有一个参数为null会抛出异常。

下面讨论一个有趣的现象,如果重载了Equals但是没有重载==运算符,会发生什么

Student s1 = neuer Student(1, „Edrick“, „Liu“, 1); 

Student s2 = neuer Student(2, „Meci“, „Luo“, 2); 

Student s3 = neuer Student(1, „Edrick“, „Liu“, 1); 

Student s4 = s3;


Console.WriteLine(s1==s3); 
Console.WriteLine(s3==s4); 
第一个为false, 第二个为true必须重载Equals.这样符合我们的意图因为集合coll[0]==co[0]其实比较的是引用但是如果我们的Equals比较的是对象的值那么最后代码还是不能按照我的期望的运行.

==运算符

==号运算符其实跟实例的Equals没有多大的区别,==是运算符,而Equals是方法。他们都可以重写.默认都能比较引用和比较值.关于==的重载可以参考运算符一文中的运算符重载.

总结他他们的区别:

ReferenceEquals :静态方法,不能重写,只能比较引用,如果有一个参数为null会返回false,不会抛出异常,如果比较值类型,则始终返回false.

Equals:实例方法,默认可以比较引用也可以比较值,可以重写。可以按值比较对象.

静态Equals:静态方法,不能重写。如果没有重写Equals,比较引用,或者比较值。如果重载了Equals方法.比较引用,或者比较值,或者按重写的Equals比较,如果其中一个参数为null,抛出异常

==运算符:可以按引用比较,也可以按值比较.可以重写.是操作运算符.

最后需要的是, 如果重载了Equals, 则最好是重载GetHashCode,必须重载==运算符.



更多Equals,ReferenceEquals,==的区别相关文章请关注PHP中文网!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn