.NET-5-判断两个对象是否为同一个对象
我们在比较两个对象的时候
如果两个对象是值类型,则直接比较的就是这两个对象在栈空间所存储的内容是否相同
如果两个对象是引用类型,比如两个自定义的类对象,他们比较的是两个对象在堆中的地址是否相同
但是string类型的比较特别,虽然string是引用类型,但是他们在比较的时候应为对其做了特殊处理,所以比较方式有点不同
值类型的不做讨论,这里比较两个引用类型的对象
一般比较两个对象是否相同使用三种方式==,Equals,object.ReferenceEquals
object.ReferenceEquals比较的才是真正的两个对象的地址
==和Equals如果被重写的话,则比较的可能不是两个对象的地址
例如string就对==运算符和Equals做了特殊处理,这里比较的就不一定是两个对象的地址
代码实例如下:
public class Class4
{
/*判断两个对象是否为同一个对象
* 指向堆里面的同一个内存空间,就是同一个对象
* 在这里只判断引用类型的是否为同一个对象
* 对值类型不做判断,对值类型判断是否为同一个对象没有意义
*
* 使用object.ReferenceEquals,可以始终准确验证两个对象是否为同一个对象
* 使用==和Equals不能保证判断的都是正确的
* 应为string有对着两个方法进行了重载或者重写导致的判断规则不同
*/
public static void Test1()
{
Console.WriteLine("自定义类:");
Person1 p = new Person1();
p.Name = "丽丽";
p.Age = 18;
Person1 p1 = new Person1();
p1.Name = "丽丽";
p1.Age = 18;
Console.WriteLine(p == p1);//false
Console.WriteLine(p.Equals(p1));//false
Console.WriteLine(object.ReferenceEquals(p, p1));//false
p = p1;
Console.WriteLine(p == p1);//true
Console.WriteLine(p.Equals(p1));//true
Console.WriteLine(object.ReferenceEquals(p, p1));//true
Console.WriteLine("string类型:");
/*string类型在使用如下的方式声明一个变量的时候
* 会在堆中查找有没有相同的对象"asd"
* 如果有,会把找到的对象的地址赋值给这个变量
* 如果没有才会创建一个新的对象,开辟一个新的空间
*/
string s1 = "asd";
string s2 = "asd";
Console.WriteLine(s1 == s2);//true
Console.WriteLine(s1.Equals(s2));//true
Console.WriteLine(object.ReferenceEquals(s1, s2));//true
Console.WriteLine("数组类型:");
/*在new string的时候,会在堆中创建一个新的空间
* 所以cs1和cs2堆的地址是不同的,他们不是同一个对象
*/
string cs1 = new string(new char[] { 'a', 'b', 'c' });
string cs2 = new string(new char[] { 'a', 'b', 'c' });
/*这里string会对运算符进行重载
* 之后会调用Equals方法进行判断
* 所以这里运算的结果和Equals的运算记过相同
*/
Console.WriteLine(cs1 == cs2);//true
/* string类中有两个Equals方法
* 一个是继承自object类并且重写的方法,他的入参是object类型
* 一个是string类自己重载的方法, 他的入参是string类型
* 这领个方法都是调用object.ReferenceEquals判断两个对象是否为同一个对象,如果是返回true
* 如果不是,则继续判断两个字符串的每个字符是否相同,如果相同返回true,不相同返回false
* 所以这里虽然两个对象不是同一个对象,但是仍然返回true
*/
Console.WriteLine(cs1.Equals(cs2));//true
Console.WriteLine(object.ReferenceEquals(cs1, cs2));//false
}
}
public class Person1
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
///// <summary>
///// 对Equals进行重写
///// </summary>
///// <param name="obj"></param>
///// <returns></returns>
//public override bool Equals(object obj)
//{
// Person1 p = obj as Person1;
// if (p == null)
// {
// return false;
// }
// else
// {
// if (this.Name == p.Name && this.Age == p.Age)
// {
// return true;
// }
// else
// {
// return false;
// }
// }
//}
///// <summary>
///// 对操作符进行重载
///// 这里写的有问题,应为下面有调用==操作符的地方,会出现递归调用。。。
///// </summary>
///// <param name="p1"></param>
///// <param name="p2"></param>
///// <returns></returns>
//public static bool operator ==(Person1 p1, Person1 p2)
//{
// return Equals(p1, p2);
//}
//public static bool operator !=(Person1 p1, Person1 p2)
//{
// return !Equals(p1, p2);
//}
//private static bool Equals(Person1 p1, Person1 p2)
//{
// if (p1 == null || p2 == null)
// {
// return false;
// }
// if (p1.Age == p2.Age && p1.Name == p2.Name)
// {
// return true;
// }
// else
// {
// return false;
// }
//}
}
string中参数为string类型的Equals方法
string中对运算符==的重载