using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
/*Equals 的默认实现支持引用相等性(对于引用类型)和按位相等性(对于值类型)。
值相等性是指所比较的对象具有相同的值,但是具有不同的二进制表示形式。
例如,请考虑两个分别表示数字 1.10 和 1.1000 的 Decimal 对象。 Decimal 对象不具有按位相等性,
* 因为它们具有不同的二进制表示形式,因此会考虑不同数量的尾随零。 但是,这些对象具有值相等性,
* 因为在进行比较时尾随零无关紧要,数字 1.10 和 1.1000 被视为相等。
*/
string s1 = "Jon";
string s2 = "Jon";
Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
s1, s2, Object.Equals(s1, s2));
string s3 = null;
string s4 = "Jon";
Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
s1, s2, Object.Equals(s3, s4));
string s5 = null;
string s6 = null;
Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
s1, s2, Object.Equals(s5, s6));
decimal d1 = 1.10m;
decimal d2 = 1.1000m;
Console.WriteLine("Object.Equals(\"{0}\", \"{1}\") => {2}",
s1, s2, Object.Equals(d1, d2));
person per = new person();
student stua = new student(2, 2, 222);
student stub = new student(2, 2, 222);
Console.WriteLine(per.Equals(stua));
Console.WriteLine(stub.Equals(stua));
Console.WriteLine(stua == stub);
object a = new object();
object b = a;
Console.WriteLine(System.Object.ReferenceEquals(a, b));
}
}
public class person : Object
{
public int x, y;
public person(int _x, int _y)
{
this.x = _x;
this.y = _y;
}
public person()
{
this.x = 1;
this.y = 1;
}
/*若要检查引用相等性,应使用 ReferenceEquals。若要检查值相等性,请使用 Equals。
下面是针对实现值类型的准则:
考虑重写 Equals,以便在 ValueType 上获得比 Equals 的默认实现所提供的性能增强的性能。
如果重写 Equals 并且语言支持运算符重载,则必须重载值类型的相等运算符。
下面是针对实现引用类型的准则:
如果引用类型的语义是基于该类型表示某个(些)值的事实,则考虑对该类型重写 Equals。
即使大多数引用类型重写 Equals,它们也必须不能重载相等运算符。
* 但是,如果实现的引用类型想要具有值语义(如复杂的数字类型),则必须重写相等运算符。
*/
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType()) return false;
person p = (person)obj;
return (p.x == x) && (p.y == y);
}
public override int GetHashCode()
{
return x ^ y;
}
}
public class student : person
{
private int z;
public student(int _x, int _y, int _z)
{
this.x = _x;
this.y = _y;
this.z = _z;
}
public override bool Equals(object obj)
{
return base.Equals(obj) && (((student)obj).z == z);
}
public override int GetHashCode()
{
return base.GetHashCode() ^ z;
}
/*
默认情况下,运算符 == 通过判断两个引用是否指示同一对象来测试引用是否相等。
* 因此引用类型不需要实现运算符 == 就能获得此功能。当类型不可变(即实例中包含的数据不可更改)时,
* 通过重载运算符 == 来比较值是否相等而不是比较引用是否相等可能会很有用,因为作为不可变的对象,只要其值相同,
* 就可以将其视为相同。建议不要在非不可变类型中重写运算符 ==。
*/
public static bool operator ==(student a, student b)
{
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
if ((object)a == null || (object)b == null)
{
return false;
}
return (a.x == b.x) && (a.y == b.y) && (a.z == b.z);
}
public static bool operator !=(student a, student b)
{
return !(a == b);
}
}
}
